QmlCompiler: Support more integer types
This adds support for 8- and 16-bit signed and unsigned integer types. The test exposes that the engine fails to correctly convert out of range values when assigning to a 32-bit int property. Fix that as drive-by. Fixes: QTBUG-101634 Change-Id: I0a4177f49ffc062a1f444e30424e94c1f293e70c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
407ed344da
commit
03ff348b49
|
@ -167,6 +167,30 @@ Module {
|
|||
valueType: "QObject"
|
||||
}
|
||||
|
||||
Component {
|
||||
name: "qint8"
|
||||
extension: "Number"
|
||||
accessSemantics: "value"
|
||||
}
|
||||
|
||||
Component {
|
||||
name: "quint8"
|
||||
extension: "Number"
|
||||
accessSemantics: "value"
|
||||
}
|
||||
|
||||
Component {
|
||||
name: "short"
|
||||
extension: "Number"
|
||||
accessSemantics: "value"
|
||||
}
|
||||
|
||||
Component {
|
||||
name: "ushort"
|
||||
extension: "Number"
|
||||
accessSemantics: "value"
|
||||
}
|
||||
|
||||
Component {
|
||||
name: "int"
|
||||
extension: "Number"
|
||||
|
@ -182,13 +206,13 @@ Module {
|
|||
}
|
||||
|
||||
Component {
|
||||
name: "qlonglong"
|
||||
accessSemantics: "value"
|
||||
name: "qlonglong"
|
||||
accessSemantics: "value"
|
||||
}
|
||||
|
||||
Component {
|
||||
name: "qulonglong"
|
||||
accessSemantics: "value"
|
||||
name: "qulonglong"
|
||||
accessSemantics: "value"
|
||||
}
|
||||
|
||||
Component {
|
||||
|
|
|
@ -602,7 +602,7 @@ void QObjectWrapper::setProperty(
|
|||
scope.engine->throwError(error);
|
||||
return;
|
||||
} else if (propType == QMetaType::fromType<int>() && value.isNumber()) {
|
||||
PROPERTY_STORE(int, value.asDouble());
|
||||
PROPERTY_STORE(int, value.toInt32());
|
||||
} else if (propType == QMetaType::fromType<qreal>() && value.isNumber()) {
|
||||
PROPERTY_STORE(qreal, qreal(value.asDouble()));
|
||||
} else if (propType == QMetaType::fromType<float>() && value.isNumber()) {
|
||||
|
|
|
@ -336,7 +336,7 @@ void QQmlJSCodeGenerator::generate_LoadConst(int index)
|
|||
m_body += conversion(
|
||||
type, m_state.accumulatorOut(),
|
||||
toNumericString(value.doubleValue()));
|
||||
} else if (type == m_typeResolver->intType()) {
|
||||
} else if (type == m_typeResolver->int32Type()) {
|
||||
m_body += conversion(
|
||||
type, m_state.accumulatorOut(),
|
||||
QString::number(value.integerValue()));
|
||||
|
@ -365,7 +365,7 @@ void QQmlJSCodeGenerator::generate_LoadZero()
|
|||
|
||||
m_body += m_state.accumulatorVariableOut;
|
||||
m_body += u" = "_s + conversion(
|
||||
m_typeResolver->intType(), m_state.accumulatorOut(), u"0"_s);
|
||||
m_typeResolver->int32Type(), m_state.accumulatorOut(), u"0"_s);
|
||||
m_body += u";\n"_s;
|
||||
}
|
||||
|
||||
|
@ -415,7 +415,7 @@ void QQmlJSCodeGenerator::generate_LoadInt(int value)
|
|||
|
||||
m_body += m_state.accumulatorVariableOut;
|
||||
m_body += u" = "_s;
|
||||
m_body += conversion(m_typeResolver->intType(), m_state.accumulatorOut(),
|
||||
m_body += conversion(m_typeResolver->int32Type(), m_state.accumulatorOut(),
|
||||
QString::number(value));
|
||||
m_body += u";\n"_s;
|
||||
}
|
||||
|
@ -446,7 +446,7 @@ void QQmlJSCodeGenerator::generate_MoveConst(int constIndex, int destTemp)
|
|||
contained = m_typeResolver->boolType();
|
||||
input = v4Value.booleanValue() ? u"true"_s : u"false"_s;
|
||||
} else if (v4Value.isInteger()) {
|
||||
contained = m_typeResolver->intType();
|
||||
contained = m_typeResolver->int32Type();
|
||||
input = QString::number(v4Value.int_32());
|
||||
} else if (v4Value.isDouble()) {
|
||||
contained = m_typeResolver->realType();
|
||||
|
@ -691,15 +691,21 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
|
|||
+ u"else "_s;
|
||||
}
|
||||
|
||||
if (!m_typeResolver->isUnsignedInteger(
|
||||
m_typeResolver->containedType(m_state.accumulatorIn()))) {
|
||||
m_body += u"if ("_s + indexName + u" < 0)\n"_s
|
||||
+ voidAssignment
|
||||
+ u"else "_s;
|
||||
}
|
||||
|
||||
if (m_typeResolver->registerIsStoredIn(baseType, m_typeResolver->listPropertyType())) {
|
||||
// Our QQmlListProperty only keeps plain QObject*.
|
||||
const auto valueType = m_typeResolver->valueType(baseType);
|
||||
const auto elementType = m_typeResolver->globalType(
|
||||
m_typeResolver->genericType(m_typeResolver->containedType(valueType)));
|
||||
|
||||
m_body += u"if ("_s + indexName + u" >= 0 && "_s + indexName
|
||||
+ u" < "_s + baseName + u".count(&"_s + baseName
|
||||
+ u"))\n"_s;
|
||||
m_body += u"if ("_s + indexName + u" < "_s + baseName
|
||||
+ u".count(&"_s + baseName + u"))\n"_s;
|
||||
m_body += u" "_s + m_state.accumulatorVariableOut + u" = "_s +
|
||||
conversion(elementType, m_state.accumulatorOut(),
|
||||
baseName + u".at(&"_s + baseName + u", "_s
|
||||
|
@ -719,8 +725,7 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
|
|||
else if (!m_typeResolver->canUseValueTypes())
|
||||
reject(u"LoadElement in sequence type reference"_s);
|
||||
|
||||
m_body += u"if ("_s + indexName + u" >= 0 && "_s + indexName
|
||||
+ u" < "_s + baseName + u".size())\n"_s;
|
||||
m_body += u"if ("_s + indexName + u" < "_s + baseName + u".size())\n"_s;
|
||||
m_body += u" "_s + m_state.accumulatorVariableOut + u" = "_s +
|
||||
conversion(elementType, m_state.accumulatorOut(), access) + u";\n"_s;
|
||||
m_body += u"else\n"_s
|
||||
|
@ -757,8 +762,9 @@ void QQmlJSCodeGenerator::generate_StoreElement(int base, int index)
|
|||
m_body += u"if ("_s;
|
||||
if (!m_typeResolver->isIntegral(indexType))
|
||||
m_body += u"QJSNumberCoercion::isInteger("_s + indexName + u") && "_s;
|
||||
m_body += indexName + u" >= 0 && "_s
|
||||
+ indexName + u" < "_s + baseName + u".count(&"_s + baseName
|
||||
if (!m_typeResolver->isUnsignedInteger(m_typeResolver->containedType(indexType)))
|
||||
m_body += indexName + u" >= 0 && "_s;
|
||||
m_body += indexName + u" < "_s + baseName + u".count(&"_s + baseName
|
||||
+ u"))\n"_s;
|
||||
m_body += u" "_s + baseName + u".replace(&"_s + baseName
|
||||
+ u", "_s + indexName + u", "_s;
|
||||
|
@ -1067,7 +1073,8 @@ void QQmlJSCodeGenerator::generate_GetLookup(int index)
|
|||
&& m_jsUnitGenerator->lookupName(index) == u"length"_s) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s;
|
||||
m_body += conversion(
|
||||
m_typeResolver->globalType(m_typeResolver->intType()), m_state.accumulatorOut(),
|
||||
m_typeResolver->globalType(m_typeResolver->int32Type()),
|
||||
m_state.accumulatorOut(),
|
||||
m_state.accumulatorVariableIn + u".count("_s + u'&'
|
||||
+ m_state.accumulatorVariableIn + u')');
|
||||
m_body += u";\n"_s;
|
||||
|
@ -1084,7 +1091,7 @@ void QQmlJSCodeGenerator::generate_GetLookup(int index)
|
|||
== QQmlJSScope::AccessSemantics::Sequence)
|
||||
&& m_jsUnitGenerator->lookupName(index) == u"length"_s) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ conversion(m_typeResolver->globalType(m_typeResolver->intType()),
|
||||
+ conversion(m_typeResolver->globalType(m_typeResolver->int32Type()),
|
||||
m_state.accumulatorOut(),
|
||||
m_state.accumulatorVariableIn + u".length()"_s)
|
||||
+ u";\n"_s;
|
||||
|
@ -1393,16 +1400,10 @@ bool QQmlJSCodeGenerator::inlineStringMethod(const QString &name, int base, int
|
|||
const QQmlJSRegisterContent input = m_state.readRegister(argv);
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s;
|
||||
|
||||
if (m_typeResolver->registerContains(input, m_typeResolver->intType()))
|
||||
m_body += ret(arg(m_typeResolver->intType()));
|
||||
else if (m_typeResolver->registerContains(input, m_typeResolver->uintType()))
|
||||
m_body += ret(arg(m_typeResolver->uintType()));
|
||||
if (m_typeResolver->isNumeric(input))
|
||||
m_body += ret(arg(m_typeResolver->containedType(input)));
|
||||
else if (m_typeResolver->registerContains(input, m_typeResolver->boolType()))
|
||||
m_body += ret(arg(m_typeResolver->boolType()));
|
||||
else if (m_typeResolver->registerContains(input, m_typeResolver->realType()))
|
||||
m_body += ret(arg(m_typeResolver->realType()));
|
||||
else if (m_typeResolver->registerContains(input, m_typeResolver->floatType()))
|
||||
m_body += ret(arg(m_typeResolver->floatType()));
|
||||
else
|
||||
m_body += ret(arg(m_typeResolver->stringType()));
|
||||
m_body += u";\n"_s;
|
||||
|
@ -1426,7 +1427,7 @@ bool QQmlJSCodeGenerator::inlineTranslateMethod(const QString &name, int argc, i
|
|||
};
|
||||
|
||||
const auto intArg = [&](int i) {
|
||||
return i < argc ? arg(i, m_typeResolver->intType()) : u"-1"_s;
|
||||
return i < argc ? arg(i, m_typeResolver->int32Type()) : u"-1"_s;
|
||||
};
|
||||
|
||||
const auto stringRet = [&](const QString &expression) {
|
||||
|
@ -2207,27 +2208,24 @@ void QQmlJSCodeGenerator::generate_CmpNeNull()
|
|||
|
||||
QString QQmlJSCodeGenerator::eqIntExpression(int lhsConst)
|
||||
{
|
||||
if (m_typeResolver->registerIsStoredIn(m_state.accumulatorIn(), m_typeResolver->intType())
|
||||
|| m_typeResolver->registerIsStoredIn(
|
||||
m_state.accumulatorIn(), m_typeResolver->uintType())) {
|
||||
if (m_typeResolver->isIntegral(m_state.accumulatorIn()))
|
||||
return QString::number(lhsConst) + u" == "_s + m_state.accumulatorVariableIn;
|
||||
}
|
||||
|
||||
if (m_typeResolver->registerIsStoredIn(m_state.accumulatorIn(), m_typeResolver->boolType())) {
|
||||
return QString::number(lhsConst) + u" == "_s
|
||||
+ convertStored(m_state.accumulatorIn().storedType(), m_typeResolver->intType(),
|
||||
+ convertStored(m_state.accumulatorIn().storedType(), m_typeResolver->int32Type(),
|
||||
consumedAccumulatorVariableIn());
|
||||
}
|
||||
|
||||
if (m_typeResolver->isNumeric(m_state.accumulatorIn())) {
|
||||
return convertStored(m_typeResolver->intType(), m_typeResolver->realType(),
|
||||
return convertStored(m_typeResolver->int32Type(), m_typeResolver->realType(),
|
||||
QString::number(lhsConst)) + u" == "_s
|
||||
+ convertStored(m_state.accumulatorIn().storedType(), m_typeResolver->realType(),
|
||||
consumedAccumulatorVariableIn());
|
||||
}
|
||||
|
||||
QString result;
|
||||
result += convertStored(m_typeResolver->intType(), m_typeResolver->jsPrimitiveType(),
|
||||
result += convertStored(m_typeResolver->int32Type(), m_typeResolver->jsPrimitiveType(),
|
||||
QString::number(lhsConst));
|
||||
result += u".equals("_s;
|
||||
result += convertStored(m_state.accumulatorIn().storedType(), m_typeResolver->jsPrimitiveType(),
|
||||
|
@ -2264,7 +2262,7 @@ QString QQmlJSCodeGenerator::contentPointer(const QQmlJSRegisterContent &content
|
|||
if (stored->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
|
||||
return u'&' + var;
|
||||
|
||||
if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->intType())
|
||||
if (m_typeResolver->isNumeric(content.storedType())
|
||||
&& m_typeResolver->containedType(content)->scopeType() == QQmlJSScope::EnumScope) {
|
||||
return u'&' + var;
|
||||
}
|
||||
|
@ -2292,10 +2290,8 @@ QString QQmlJSCodeGenerator::contentType(const QQmlJSRegisterContent &content, c
|
|||
if (stored->accessSemantics() == QQmlJSScope::AccessSemantics::Reference)
|
||||
return metaTypeFromName(contained);
|
||||
|
||||
if (m_typeResolver->registerIsStoredIn(content, m_typeResolver->intType())
|
||||
&& m_typeResolver->containedType(content)->scopeType() == QQmlJSScope::EnumScope) {
|
||||
return metaTypeFromType(m_typeResolver->intType());
|
||||
}
|
||||
if (m_typeResolver->isNumeric(stored) && contained->scopeType() == QQmlJSScope::EnumScope)
|
||||
return metaTypeFromType(contained->baseType());
|
||||
|
||||
if (stored->isListProperty() && m_typeResolver->containedType(content)->isListProperty())
|
||||
return metaTypeFromType(m_typeResolver->listPropertyType());
|
||||
|
@ -2832,7 +2828,7 @@ void QQmlJSCodeGenerator::generateArithmeticConstOperation(int rhsConst, const Q
|
|||
generateArithmeticOperation(
|
||||
conversion(m_state.accumulatorIn(), m_state.readAccumulator(),
|
||||
consumedAccumulatorVariableIn()),
|
||||
conversion(m_typeResolver->globalType(m_typeResolver->intType()),
|
||||
conversion(m_typeResolver->globalType(m_typeResolver->int32Type()),
|
||||
m_state.readAccumulator(), QString::number(rhsConst)),
|
||||
cppOperator);
|
||||
}
|
||||
|
@ -3017,7 +3013,7 @@ QString QQmlJSCodeGenerator::conversion(
|
|||
const QString conversion = variable + u".to<QJSPrimitiveValue::%1>()"_s;
|
||||
if (m_typeResolver->equals(contained, m_typeResolver->boolType()))
|
||||
return conversion.arg(u"Boolean"_s);
|
||||
if (m_typeResolver->equals(contained, m_typeResolver->intType()))
|
||||
if (m_typeResolver->isIntegral(to))
|
||||
return conversion.arg(u"Integer"_s);
|
||||
if (m_typeResolver->equals(contained, m_typeResolver->realType()))
|
||||
return conversion.arg(u"Double"_s);
|
||||
|
@ -3027,12 +3023,12 @@ QString QQmlJSCodeGenerator::conversion(
|
|||
}
|
||||
|
||||
if (m_typeResolver->registerIsStoredIn(to, contained)
|
||||
|| m_typeResolver->registerIsStoredIn(from, m_typeResolver->intType())
|
||||
|| m_typeResolver->isNumeric(from.storedType())
|
||||
|| to.storedType()->isReferenceType()
|
||||
|| m_typeResolver->registerContains(from, contained)) {
|
||||
// If:
|
||||
// * the output is not actually wrapped at all, or
|
||||
// * the input is stored in an int (as there are no internals to an int), or
|
||||
// * the input is stored in a numeric type (as there are no internals to a number), or
|
||||
// * the output is a QObject pointer, or
|
||||
// * we merely wrap the value into a new container,
|
||||
// we can convert by stored type.
|
||||
|
@ -3057,9 +3053,9 @@ QString QQmlJSCodeGenerator::convertStored(
|
|||
auto zeroBoolOrInt = [&](const QQmlJSScope::ConstPtr &to) {
|
||||
if (m_typeResolver->equals(to, boolType))
|
||||
return u"false"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->intType()))
|
||||
if (m_typeResolver->isSignedInteger(to))
|
||||
return u"0"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->uintType()))
|
||||
if (m_typeResolver->isUnsignedInteger(to))
|
||||
return u"0u"_s;
|
||||
return QString();
|
||||
};
|
||||
|
@ -3153,9 +3149,9 @@ QString QQmlJSCodeGenerator::convertStored(
|
|||
|
||||
if (m_typeResolver->equals(from, m_typeResolver->realType())
|
||||
|| m_typeResolver->equals(from, m_typeResolver->floatType())) {
|
||||
if (m_typeResolver->equals(to, m_typeResolver->intType()))
|
||||
if (m_typeResolver->isSignedInteger(to))
|
||||
return u"QJSNumberCoercion::toInteger("_s + variable + u')';
|
||||
if (m_typeResolver->equals(to, m_typeResolver->uintType()))
|
||||
if (m_typeResolver->isUnsignedInteger(to))
|
||||
return u"uint(QJSNumberCoercion::toInteger("_s + variable + u"))"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->boolType()))
|
||||
return u'(' + variable + u" && !std::isnan("_s + variable + u"))"_s;
|
||||
|
@ -3170,9 +3166,9 @@ QString QQmlJSCodeGenerator::convertStored(
|
|||
return variable + u".toDouble()"_s;
|
||||
if (m_typeResolver->equals(to, boolType))
|
||||
return variable + u".toBoolean()"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->intType()))
|
||||
if (m_typeResolver->isSignedInteger(to))
|
||||
return variable + u".toInteger()"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->uintType()))
|
||||
if (m_typeResolver->isUnsignedInteger(to))
|
||||
return u"uint("_s + variable + u".toInteger())"_s;
|
||||
if (m_typeResolver->equals(to, m_typeResolver->stringType()))
|
||||
return variable + u".toString()"_s;
|
||||
|
@ -3198,10 +3194,14 @@ QString QQmlJSCodeGenerator::convertStored(
|
|||
Q_ASSERT(!m_typeResolver->equals(from, m_typeResolver->voidType()));
|
||||
|
||||
if (m_typeResolver->equals(from, m_typeResolver->boolType())
|
||||
|| m_typeResolver->equals(from, m_typeResolver->intType())
|
||||
|| m_typeResolver->equals(from, m_typeResolver->int32Type())
|
||||
|| m_typeResolver->equals(from, m_typeResolver->realType())
|
||||
|| m_typeResolver->equals(from, m_typeResolver->stringType())) {
|
||||
return u"QJSPrimitiveValue("_s + variable + u')';
|
||||
} else if (m_typeResolver->isSignedInteger(from)
|
||||
|| m_typeResolver->equals(from, m_typeResolver->uint16Type())
|
||||
|| m_typeResolver->equals(from, m_typeResolver->uint8Type())) {
|
||||
return u"QJSPrimitiveValue(int("_s + variable + u"))"_s;
|
||||
} else if (m_typeResolver->isNumeric(from)) {
|
||||
return u"QJSPrimitiveValue(double("_s + variable + u"))"_s;
|
||||
}
|
||||
|
@ -3264,9 +3264,9 @@ QString QQmlJSCodeGenerator::convertStored(
|
|||
{
|
||||
if (m_typeResolver->equals(type, m_typeResolver->boolType()))
|
||||
return expression + u".toBoolean()"_s;
|
||||
if (m_typeResolver->equals(type, m_typeResolver->intType()))
|
||||
if (m_typeResolver->isSignedInteger(type))
|
||||
return expression + u".toInteger()"_s;
|
||||
if (m_typeResolver->equals(type, m_typeResolver->uintType()))
|
||||
if (m_typeResolver->isUnsignedInteger(type))
|
||||
return u"uint("_s + expression + u".toInteger())"_s;
|
||||
if (m_typeResolver->equals(type, m_typeResolver->realType()))
|
||||
return expression + u".toDouble()"_s;
|
||||
|
@ -3321,7 +3321,7 @@ QString QQmlJSCodeGenerator::convertContained(const QQmlJSRegisterContent &from,
|
|||
// Those should be handled before, by convertStored().
|
||||
Q_ASSERT(!to.storedType()->isReferenceType());
|
||||
Q_ASSERT(!m_typeResolver->registerIsStoredIn(to, containedTo));
|
||||
Q_ASSERT(!m_typeResolver->registerIsStoredIn(from, m_typeResolver->intType()));
|
||||
Q_ASSERT(!m_typeResolver->isIntegral(from.storedType()));
|
||||
Q_ASSERT(!m_typeResolver->equals(containedFrom, containedTo));
|
||||
|
||||
if (!m_typeResolver->registerIsStoredIn(to, m_typeResolver->varType()) &&
|
||||
|
|
|
@ -122,7 +122,7 @@ void QQmlJSTypePropagator::generate_LoadConst(int index)
|
|||
|
||||
void QQmlJSTypePropagator::generate_LoadZero()
|
||||
{
|
||||
setAccumulator(m_typeResolver->globalType(m_typeResolver->intType()));
|
||||
setAccumulator(m_typeResolver->globalType(m_typeResolver->int32Type()));
|
||||
}
|
||||
|
||||
void QQmlJSTypePropagator::generate_LoadTrue()
|
||||
|
@ -147,7 +147,7 @@ void QQmlJSTypePropagator::generate_LoadUndefined()
|
|||
|
||||
void QQmlJSTypePropagator::generate_LoadInt(int)
|
||||
{
|
||||
setAccumulator(m_typeResolver->globalType(m_typeResolver->intType()));
|
||||
setAccumulator(m_typeResolver->globalType(m_typeResolver->int32Type()));
|
||||
}
|
||||
|
||||
void QQmlJSTypePropagator::generate_MoveConst(int constIndex, int destTemp)
|
||||
|
@ -669,8 +669,11 @@ void QQmlJSTypePropagator::generate_LoadElement(int base)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->isIntegral(m_state.accumulatorIn()))
|
||||
addReadAccumulator(m_typeResolver->globalType(m_typeResolver->intType()));
|
||||
const auto contained = m_typeResolver->containedType(m_state.accumulatorIn());
|
||||
if (m_typeResolver->isSignedInteger(contained))
|
||||
addReadAccumulator(m_typeResolver->globalType(m_typeResolver->int32Type()));
|
||||
else if (m_typeResolver->isUnsignedInteger(contained))
|
||||
addReadAccumulator(m_typeResolver->globalType(m_typeResolver->uint32Type()));
|
||||
else
|
||||
addReadAccumulator(m_typeResolver->globalType(m_typeResolver->realType()));
|
||||
|
||||
|
@ -699,8 +702,11 @@ void QQmlJSTypePropagator::generate_StoreElement(int base, int index)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->isIntegral(indexRegister))
|
||||
addReadRegister(index, m_typeResolver->globalType(m_typeResolver->intType()));
|
||||
const auto contained = m_typeResolver->containedType(indexRegister);
|
||||
if (m_typeResolver->isSignedInteger(contained))
|
||||
addReadRegister(index, m_typeResolver->globalType(m_typeResolver->int32Type()));
|
||||
else if (m_typeResolver->isUnsignedInteger(contained))
|
||||
addReadRegister(index, m_typeResolver->globalType(m_typeResolver->uint32Type()));
|
||||
else
|
||||
addReadRegister(index, m_typeResolver->globalType(m_typeResolver->realType()));
|
||||
|
||||
|
@ -1261,7 +1267,7 @@ bool QQmlJSTypePropagator::propagateTranslationMethod(
|
|||
|
||||
const QQmlJSMetaMethod method = methods.front();
|
||||
const QQmlJSRegisterContent intType
|
||||
= m_typeResolver->globalType(m_typeResolver->intType());
|
||||
= m_typeResolver->globalType(m_typeResolver->int32Type());
|
||||
const QQmlJSRegisterContent stringType
|
||||
= m_typeResolver->globalType(m_typeResolver->stringType());
|
||||
const QQmlJSRegisterContent returnType
|
||||
|
@ -1370,17 +1376,25 @@ void QQmlJSTypePropagator::propagateStringArgCall(int argv)
|
|||
|
||||
const QQmlJSScope::ConstPtr input = m_typeResolver->containedType(
|
||||
m_state.registers[argv].content);
|
||||
for (QQmlJSScope::ConstPtr targetType : {
|
||||
m_typeResolver->intType(),
|
||||
m_typeResolver->uintType(),
|
||||
m_typeResolver->realType(),
|
||||
m_typeResolver->floatType(),
|
||||
m_typeResolver->boolType(),
|
||||
}) {
|
||||
if (m_typeResolver->equals(input, targetType)) {
|
||||
addReadRegister(argv, m_typeResolver->globalType(targetType));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->equals(input, m_typeResolver->uint32Type())) {
|
||||
addReadRegister(argv, m_typeResolver->globalType(m_typeResolver->realType()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->isIntegral(input)) {
|
||||
addReadRegister(argv, m_typeResolver->globalType(m_typeResolver->int32Type()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->isNumeric(input)) {
|
||||
addReadRegister(argv, m_typeResolver->globalType(m_typeResolver->realType()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->equals(input, m_typeResolver->boolType())) {
|
||||
addReadRegister(argv, m_typeResolver->globalType(m_typeResolver->boolType()));
|
||||
return;
|
||||
}
|
||||
|
||||
addReadRegister(argv, m_typeResolver->globalType(m_typeResolver->stringType()));
|
||||
|
@ -1779,10 +1793,11 @@ void QQmlJSTypePropagator::recordEqualsType(int lhs)
|
|||
};
|
||||
|
||||
const auto isIntCompatible = [this](const QQmlJSRegisterContent &content) {
|
||||
const QQmlJSScope::ConstPtr contained = m_typeResolver->containedType(content);
|
||||
return contained->scopeType() == QQmlJSScope::EnumScope
|
||||
|| m_typeResolver->equals(contained, m_typeResolver->intType())
|
||||
|| m_typeResolver->equals(contained, m_typeResolver->uintType());
|
||||
auto contained = m_typeResolver->containedType(content);
|
||||
if (contained->scopeType() == QQmlJSScope::EnumScope)
|
||||
contained = contained->baseType();
|
||||
return m_typeResolver->isIntegral(contained)
|
||||
&& !m_typeResolver->equals(contained, m_typeResolver->uint32Type());
|
||||
};
|
||||
|
||||
const auto accumulatorIn = m_state.accumulatorIn();
|
||||
|
@ -1797,7 +1812,7 @@ void QQmlJSTypePropagator::recordEqualsType(int lhs)
|
|||
return;
|
||||
} else if (isNumericOrEnum(accumulatorIn) && isNumericOrEnum(lhsRegister)) {
|
||||
const auto targetType = isIntCompatible(accumulatorIn) && isIntCompatible(lhsRegister)
|
||||
? m_typeResolver->globalType(m_typeResolver->intType())
|
||||
? m_typeResolver->globalType(m_typeResolver->int32Type())
|
||||
: m_typeResolver->globalType(m_typeResolver->realType());
|
||||
addReadRegister(lhs, targetType);
|
||||
addReadAccumulator(targetType);
|
||||
|
@ -1858,7 +1873,7 @@ void QQmlJSTypePropagator::generate_CmpEqInt(int lhsConst)
|
|||
recordEqualsIntType();
|
||||
Q_UNUSED(lhsConst)
|
||||
setAccumulator(QQmlJSRegisterContent(m_typeResolver->typeForBinaryOperation(
|
||||
QSOperator::Op::Equal, m_typeResolver->globalType(m_typeResolver->intType()),
|
||||
QSOperator::Op::Equal, m_typeResolver->globalType(m_typeResolver->int32Type()),
|
||||
m_state.accumulatorIn())));
|
||||
}
|
||||
|
||||
|
@ -1867,7 +1882,7 @@ void QQmlJSTypePropagator::generate_CmpNeInt(int lhsConst)
|
|||
recordEqualsIntType();
|
||||
Q_UNUSED(lhsConst)
|
||||
setAccumulator(QQmlJSRegisterContent(m_typeResolver->typeForBinaryOperation(
|
||||
QSOperator::Op::NotEqual, m_typeResolver->globalType(m_typeResolver->intType()),
|
||||
QSOperator::Op::NotEqual, m_typeResolver->globalType(m_typeResolver->int32Type()),
|
||||
m_state.accumulatorIn())));
|
||||
}
|
||||
|
||||
|
@ -2040,7 +2055,7 @@ void QQmlJSTypePropagator::generateBinaryConstArithmeticOperation(QSOperator::Op
|
|||
{
|
||||
const QQmlJSRegisterContent type = m_typeResolver->typeForBinaryOperation(
|
||||
op, m_state.accumulatorIn(),
|
||||
m_typeResolver->builtinType(m_typeResolver->intType()));
|
||||
m_typeResolver->builtinType(m_typeResolver->int32Type()));
|
||||
|
||||
checkConversion(m_state.accumulatorIn(), type);
|
||||
addReadAccumulator(type);
|
||||
|
|
|
@ -28,8 +28,14 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer)
|
|||
m_nullType = builtinTypes.type(u"std::nullptr_t"_s).scope;
|
||||
m_realType = builtinTypes.type(u"double"_s).scope;
|
||||
m_floatType = builtinTypes.type(u"float"_s).scope;
|
||||
m_intType = builtinTypes.type(u"int"_s).scope;
|
||||
m_uintType = builtinTypes.type(u"uint"_s).scope;
|
||||
m_int8Type = builtinTypes.type(u"qint8"_s).scope;
|
||||
m_uint8Type = builtinTypes.type(u"quint8"_s).scope;
|
||||
m_int16Type = builtinTypes.type(u"short"_s).scope;
|
||||
m_uint16Type = builtinTypes.type(u"ushort"_s).scope;
|
||||
m_int32Type = builtinTypes.type(u"int"_s).scope;
|
||||
m_uint32Type = builtinTypes.type(u"uint"_s).scope;
|
||||
m_int64Type = builtinTypes.type(u"qlonglong"_s).scope;
|
||||
m_uint64Type = builtinTypes.type(u"qulonglong"_s).scope;
|
||||
m_boolType = builtinTypes.type(u"bool"_s).scope;
|
||||
m_stringType = builtinTypes.type(u"QString"_s).scope;
|
||||
m_stringListType = builtinTypes.type(u"QStringList"_s).scope;
|
||||
|
@ -147,7 +153,7 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::typeForConst(QV4::ReturnedValue rv) co
|
|||
return voidType();
|
||||
|
||||
if (value.isInt32())
|
||||
return intType();
|
||||
return int32Type();
|
||||
|
||||
if (value.isBoolean())
|
||||
return boolType();
|
||||
|
@ -187,9 +193,9 @@ QQmlJSTypeResolver::typeForBinaryOperation(QSOperator::Op oper, const QQmlJSRegi
|
|||
case QSOperator::Op::BitXor:
|
||||
case QSOperator::Op::LShift:
|
||||
case QSOperator::Op::RShift:
|
||||
return builtinType(intType());
|
||||
return builtinType(int32Type());
|
||||
case QSOperator::Op::URShift:
|
||||
return builtinType(uintType());
|
||||
return builtinType(uint32Type());
|
||||
case QSOperator::Op::Add: {
|
||||
const auto leftContents = containedType(left);
|
||||
const auto rightContents = containedType(right);
|
||||
|
@ -198,7 +204,7 @@ QQmlJSTypeResolver::typeForBinaryOperation(QSOperator::Op oper, const QQmlJSRegi
|
|||
|
||||
const QQmlJSScope::ConstPtr result = merge(leftContents, rightContents);
|
||||
if (equals(result, boolType()))
|
||||
return builtinType(intType());
|
||||
return builtinType(int32Type());
|
||||
if (isNumeric(result))
|
||||
return builtinType(realType());
|
||||
|
||||
|
@ -208,7 +214,7 @@ QQmlJSTypeResolver::typeForBinaryOperation(QSOperator::Op oper, const QQmlJSRegi
|
|||
case QSOperator::Op::Mul:
|
||||
case QSOperator::Op::Exp: {
|
||||
const QQmlJSScope::ConstPtr result = merge(containedType(left), containedType(right));
|
||||
return builtinType(equals(result, boolType()) ? intType() : realType());
|
||||
return builtinType(equals(result, boolType()) ? int32Type() : realType());
|
||||
}
|
||||
case QSOperator::Op::Div:
|
||||
case QSOperator::Op::Mod:
|
||||
|
@ -229,14 +235,14 @@ QQmlJSRegisterContent QQmlJSTypeResolver::typeForArithmeticUnaryOperation(
|
|||
case UnaryOperator::Not:
|
||||
return builtinType(boolType());
|
||||
case UnaryOperator::Complement:
|
||||
return builtinType(intType());
|
||||
return builtinType(int32Type());
|
||||
case UnaryOperator::Plus:
|
||||
if (isIntegral(operand))
|
||||
return operand;
|
||||
Q_FALLTHROUGH();
|
||||
default:
|
||||
if (equals(containedType(operand), boolType()))
|
||||
return builtinType(intType());
|
||||
return builtinType(int32Type());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -255,13 +261,18 @@ bool QQmlJSTypeResolver::isNumeric(const QQmlJSRegisterContent &type) const
|
|||
|
||||
bool QQmlJSTypeResolver::isIntegral(const QQmlJSRegisterContent &type) const
|
||||
{
|
||||
return equals(containedType(type), m_intType) || equals(containedType(type), m_uintType);
|
||||
return isIntegral(containedType(type));
|
||||
}
|
||||
|
||||
bool QQmlJSTypeResolver::isIntegral(const QQmlJSScope::ConstPtr &type) const
|
||||
{
|
||||
// Only types of length <= 32bit count as integral
|
||||
return isSignedInteger(type) || isUnsignedInteger(type);
|
||||
}
|
||||
|
||||
bool QQmlJSTypeResolver::isPrimitive(const QQmlJSScope::ConstPtr &type) const
|
||||
{
|
||||
return equals(type, m_intType) || equals(type, m_uintType)
|
||||
|| equals(type, m_realType) || equals(type, m_floatType)
|
||||
return isNumeric(type)
|
||||
|| equals(type, m_boolType) || equals(type, m_voidType) || equals(type, m_nullType)
|
||||
|| equals(type, m_stringType) || equals(type, m_jsPrimitiveType);
|
||||
}
|
||||
|
@ -273,7 +284,23 @@ bool QQmlJSTypeResolver::isNumeric(const QQmlJSScope::ConstPtr &type) const
|
|||
if (mode == QQmlJSScope::ExtensionNamespace)
|
||||
return false;
|
||||
return equals(scope, m_numberPrototype);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
bool QQmlJSTypeResolver::isSignedInteger(const QQmlJSScope::ConstPtr &type) const
|
||||
{
|
||||
// Only types of length <= 32bit count as integral
|
||||
return equals(type, m_int8Type)
|
||||
|| equals(type, m_int16Type)
|
||||
|| equals(type, m_int32Type);
|
||||
}
|
||||
|
||||
bool QQmlJSTypeResolver::isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const
|
||||
{
|
||||
// Only types of length <= 32bit count as integral
|
||||
return equals(type, m_uint8Type)
|
||||
|| equals(type, m_uint16Type)
|
||||
|| equals(type, m_uint32Type);
|
||||
}
|
||||
|
||||
QQmlJSScope::ConstPtr
|
||||
|
@ -623,21 +650,31 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::merge(const QQmlJSScope::ConstPtr &a,
|
|||
if (equals(b, jsValueType()) || equals(b, varType()))
|
||||
return b;
|
||||
|
||||
auto canConvert = [&](const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) {
|
||||
return (equals(a, from) && equals(b, to)) || (equals(b, from) && equals(a, to));
|
||||
const auto isInt32Compatible = [&](const QQmlJSScope::ConstPtr &type) {
|
||||
return (isIntegral(type) && !equals(type, uint32Type())) || equals(type, boolType());
|
||||
};
|
||||
|
||||
if (isInt32Compatible(a) && isInt32Compatible(b))
|
||||
return int32Type();
|
||||
|
||||
const auto isUInt32Compatible = [&](const QQmlJSScope::ConstPtr &type) {
|
||||
return isUnsignedInteger(type) || equals(type, boolType());
|
||||
};
|
||||
|
||||
if (isUInt32Compatible(a) && isUInt32Compatible(b))
|
||||
return uint32Type();
|
||||
|
||||
if (isNumeric(a) && isNumeric(b))
|
||||
return realType();
|
||||
|
||||
if (canConvert(boolType(), intType()))
|
||||
return intType();
|
||||
if (canConvert(boolType(), uintType()))
|
||||
return uintType();
|
||||
if (canConvert(intType(), stringType()))
|
||||
return stringType();
|
||||
if (canConvert(uintType(), stringType()))
|
||||
const auto isStringCompatible = [&](const QQmlJSScope::ConstPtr &type) {
|
||||
// TODO: We can losslessly coerce more types to string. Should we?
|
||||
return isIntegral(type) || equals(type, stringType());
|
||||
};
|
||||
|
||||
if (isStringCompatible(a) && isStringCompatible(b))
|
||||
return stringType();
|
||||
|
||||
if (isPrimitive(a) && isPrimitive(b))
|
||||
return jsPrimitiveType();
|
||||
|
||||
|
@ -765,6 +802,9 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType(
|
|||
if (type->isListProperty())
|
||||
return m_listPropertyType;
|
||||
|
||||
if (type->scopeType() == QQmlJSScope::EnumScope)
|
||||
return type->baseType();
|
||||
|
||||
if (isPrimitive(type) || equals(type, m_jsValueType) || equals(type, m_urlType)
|
||||
|| equals(type, m_dateTimeType) || equals(type, m_dateType) || equals(type, m_timeType)
|
||||
|| equals(type, m_variantListType) || equals(type, m_variantMapType)
|
||||
|
@ -773,12 +813,6 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType(
|
|||
return type;
|
||||
}
|
||||
|
||||
if (type->scopeType() == QQmlJSScope::EnumScope)
|
||||
return m_intType;
|
||||
|
||||
if (isNumeric(type))
|
||||
return m_realType;
|
||||
|
||||
if (type->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence) {
|
||||
if (const QQmlJSScope::ConstPtr valueType = type->valueType()) {
|
||||
switch (valueType->accessSemantics()) {
|
||||
|
@ -944,7 +978,7 @@ bool QQmlJSTypeResolver::checkEnums(const QQmlJSScope::ConstPtr &scope, const QS
|
|||
for (const auto &enumeration : enums) {
|
||||
if (enumeration.name() == name) {
|
||||
*result = QQmlJSRegisterContent::create(
|
||||
storedType(intType()), enumeration, QString(),
|
||||
storedType(enumeration.type()), enumeration, QString(),
|
||||
inExtension ? QQmlJSRegisterContent::ExtensionObjectEnum
|
||||
: QQmlJSRegisterContent::ObjectEnum,
|
||||
scope);
|
||||
|
@ -953,7 +987,7 @@ bool QQmlJSTypeResolver::checkEnums(const QQmlJSScope::ConstPtr &scope, const QS
|
|||
|
||||
if (enumeration.hasKey(name)) {
|
||||
*result = QQmlJSRegisterContent::create(
|
||||
storedType(intType()), enumeration, name,
|
||||
storedType(enumeration.type()), enumeration, name,
|
||||
inExtension ? QQmlJSRegisterContent::ExtensionObjectEnum
|
||||
: QQmlJSRegisterContent::ObjectEnum,
|
||||
scope);
|
||||
|
@ -1109,9 +1143,9 @@ QQmlJSRegisterContent QQmlJSTypeResolver::lengthProperty(
|
|||
QQmlJSMetaProperty prop;
|
||||
prop.setPropertyName(u"length"_s);
|
||||
prop.setTypeName(u"int"_s);
|
||||
prop.setType(intType());
|
||||
prop.setType(int32Type());
|
||||
prop.setIsWritable(isWritable);
|
||||
return QQmlJSRegisterContent::create(intType(), prop, QQmlJSRegisterContent::Builtin, scope);
|
||||
return QQmlJSRegisterContent::create(int32Type(), prop, QQmlJSRegisterContent::Builtin, scope);
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSScope::ConstPtr &type,
|
||||
|
@ -1252,7 +1286,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSRegisterContent
|
|||
const auto enumeration = type.enumeration();
|
||||
if (!type.enumMember().isEmpty() || !enumeration.hasKey(name))
|
||||
return {};
|
||||
return QQmlJSRegisterContent::create(storedType(intType()), enumeration, name,
|
||||
return QQmlJSRegisterContent::create(storedType(enumeration.type()), enumeration, name,
|
||||
QQmlJSRegisterContent::ObjectEnum, type.scopeType());
|
||||
}
|
||||
if (type.isMethod()) {
|
||||
|
|
|
@ -45,8 +45,14 @@ public:
|
|||
QQmlJSScope::ConstPtr nullType() const { return m_nullType; }
|
||||
QQmlJSScope::ConstPtr realType() const { return m_realType; }
|
||||
QQmlJSScope::ConstPtr floatType() const { return m_floatType; }
|
||||
QQmlJSScope::ConstPtr intType() const { return m_intType; }
|
||||
QQmlJSScope::ConstPtr uintType() const { return m_uintType; }
|
||||
QQmlJSScope::ConstPtr int8Type() const { return m_int8Type; }
|
||||
QQmlJSScope::ConstPtr uint8Type() const { return m_uint8Type; }
|
||||
QQmlJSScope::ConstPtr int16Type() const { return m_int16Type; }
|
||||
QQmlJSScope::ConstPtr uint16Type() const { return m_uint16Type; }
|
||||
QQmlJSScope::ConstPtr int32Type() const { return m_int32Type; }
|
||||
QQmlJSScope::ConstPtr uint32Type() const { return m_uint32Type; }
|
||||
QQmlJSScope::ConstPtr int64Type() const { return m_int64Type; }
|
||||
QQmlJSScope::ConstPtr uint64Type() const { return m_uint64Type; }
|
||||
QQmlJSScope::ConstPtr boolType() const { return m_boolType; }
|
||||
QQmlJSScope::ConstPtr stringType() const { return m_stringType; }
|
||||
QQmlJSScope::ConstPtr stringListType() const { return m_stringListType; }
|
||||
|
@ -166,6 +172,9 @@ public:
|
|||
|
||||
bool canHoldUndefined(const QQmlJSRegisterContent &content) const;
|
||||
bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
|
||||
bool isIntegral(const QQmlJSScope::ConstPtr &type) const;
|
||||
bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const;
|
||||
bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const;
|
||||
|
||||
bool canHold(const QQmlJSScope::ConstPtr &container,
|
||||
const QQmlJSScope::ConstPtr &contained) const;
|
||||
|
@ -202,8 +211,14 @@ protected:
|
|||
QQmlJSScope::ConstPtr m_arrayType;
|
||||
QQmlJSScope::ConstPtr m_realType;
|
||||
QQmlJSScope::ConstPtr m_floatType;
|
||||
QQmlJSScope::ConstPtr m_intType;
|
||||
QQmlJSScope::ConstPtr m_uintType;
|
||||
QQmlJSScope::ConstPtr m_int8Type;
|
||||
QQmlJSScope::ConstPtr m_uint8Type;
|
||||
QQmlJSScope::ConstPtr m_int16Type;
|
||||
QQmlJSScope::ConstPtr m_uint16Type;
|
||||
QQmlJSScope::ConstPtr m_int32Type;
|
||||
QQmlJSScope::ConstPtr m_uint32Type;
|
||||
QQmlJSScope::ConstPtr m_int64Type;
|
||||
QQmlJSScope::ConstPtr m_uint64Type;
|
||||
QQmlJSScope::ConstPtr m_boolType;
|
||||
QQmlJSScope::ConstPtr m_stringType;
|
||||
QQmlJSScope::ConstPtr m_stringListType;
|
||||
|
|
|
@ -187,6 +187,10 @@ void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key)
|
|||
#else
|
||||
type = QLatin1String("double");
|
||||
#endif
|
||||
} else if (type == QLatin1String("qint16")) {
|
||||
type = QLatin1String("short");
|
||||
} else if (type == QLatin1String("quint16")) {
|
||||
type = QLatin1String("ushort");
|
||||
} else if (type == QLatin1String("qint32")) {
|
||||
type = QLatin1String("int");
|
||||
} else if (type == QLatin1String("quint32")) {
|
||||
|
|
|
@ -4,23 +4,57 @@ import TestTypes
|
|||
|
||||
QtObject {
|
||||
function writeValues() {
|
||||
Druggeljug.myInt8 = 35
|
||||
Druggeljug.myUint8 = 36
|
||||
Druggeljug.myInt16 = 37
|
||||
Druggeljug.myUint16 = 38
|
||||
Druggeljug.myInt = 39
|
||||
Druggeljug.myUint = 40
|
||||
Druggeljug.myInt32 = 41
|
||||
Druggeljug.myUint32 = 42
|
||||
}
|
||||
|
||||
function negateValues() {
|
||||
Druggeljug.myInt8 = -Druggeljug.myInt8;
|
||||
Druggeljug.myUint8 = -Druggeljug.myUint8;
|
||||
Druggeljug.myInt16 = -Druggeljug.myInt16;
|
||||
Druggeljug.myUint16 = -Druggeljug.myUint16;
|
||||
Druggeljug.myInt = -Druggeljug.myInt;
|
||||
Druggeljug.myUint = -Druggeljug.myUint;
|
||||
Druggeljug.myInt32 = -Druggeljug.myInt32;
|
||||
Druggeljug.myUint32 = -Druggeljug.myUint32;
|
||||
}
|
||||
|
||||
function shuffleValues() {
|
||||
Druggeljug.myInt8 = Druggeljug.myUint8;
|
||||
Druggeljug.myUint8 = Druggeljug.myInt16;
|
||||
Druggeljug.myInt16 = Druggeljug.myUint16;
|
||||
Druggeljug.myUint16 = Druggeljug.myInt;
|
||||
Druggeljug.myInt = Druggeljug.myUint;
|
||||
Druggeljug.myUint = Druggeljug.myInt32;
|
||||
Druggeljug.myInt32 = Druggeljug.myUint32;
|
||||
Druggeljug.myUint32 = Druggeljug.myInt8;
|
||||
}
|
||||
|
||||
function readValueAsString(i: int) : string {
|
||||
switch (i) {
|
||||
case 0: return Druggeljug.myInt;
|
||||
case 1: return Druggeljug.myUint;
|
||||
case 2: return Druggeljug.myInt32;
|
||||
case 3: return Druggeljug.myUint32;
|
||||
case 0: return Druggeljug.myInt8;
|
||||
case 1: return Druggeljug.myUint8;
|
||||
case 2: return Druggeljug.myInt16;
|
||||
case 3: return Druggeljug.myUint16;
|
||||
case 4: return Druggeljug.myInt;
|
||||
case 5: return Druggeljug.myUint;
|
||||
case 6: return Druggeljug.myInt32;
|
||||
case 7: return Druggeljug.myUint32;
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
function storeValues() {
|
||||
Druggeljug.storeMyInt8(1330)
|
||||
Druggeljug.storeMyUint8(1331)
|
||||
Druggeljug.storeMyInt16(1332)
|
||||
Druggeljug.storeMyUint16(1333)
|
||||
Druggeljug.storeMyInt(1334)
|
||||
Druggeljug.storeMyUint(1335)
|
||||
Druggeljug.storeMyInt32(1336)
|
||||
|
|
|
@ -3043,10 +3043,10 @@ void tst_QmlCppCodegen::lengthAccessArraySequenceCompat()
|
|||
QCOMPARE(o->property("length").toInt(), 100);
|
||||
}
|
||||
|
||||
static QList<QString> convertToStrings(const QList<int> &ints)
|
||||
static QList<QString> convertToStrings(const QList<qint64> &ints)
|
||||
{
|
||||
QList<QString> strings;
|
||||
for (int i : ints)
|
||||
for (qint64 i : ints)
|
||||
strings.append(QString::number(i));
|
||||
return strings;
|
||||
}
|
||||
|
@ -3059,12 +3059,41 @@ void tst_QmlCppCodegen::numbersInJsPrimitive()
|
|||
QScopedPointer<QObject> o(c.create());
|
||||
QVERIFY(!o.isNull());
|
||||
|
||||
const QList<int> zeroes = {0, 0, 0, 0};
|
||||
const QList<int> written = {39, 40, 41, 42};
|
||||
const QList<int> stored = {1334, 1335, 1336, 1337};
|
||||
QStringList asStrings(4);
|
||||
const QList<qint64> zeroes
|
||||
= {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
const QList<qint64> written
|
||||
= {35, 36, 37, 38, 39, 40, 41, 42};
|
||||
const QList<qint64> writtenNegative
|
||||
= {-35, 220, -37, 65498, -39, 4294967256, -41, 4294967254};
|
||||
const QList<QList<qint64>> writtenShuffled = {
|
||||
{ -36, 219, -38, 65497, -40, 4294967255, -42, 4294967260 },
|
||||
{ -37, 218, -39, 65496, -41, 4294967254, -36, 4294967259 },
|
||||
{ -38, 217, -40, 65495, -42, 4294967260, -37, 4294967258 },
|
||||
{ -39, 216, -41, 65494, -36, 4294967259, -38, 4294967257 },
|
||||
{ -40, 215, -42, 65500, -37, 4294967258, -39, 4294967256 },
|
||||
{ -41, 214, -36, 65499, -38, 4294967257, -40, 4294967255 },
|
||||
{ -42, 220, -37, 65498, -39, 4294967256, -41, 4294967254 },
|
||||
{ -36, 219, -38, 65497, -40, 4294967255, -42, 4294967260 },
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
const QList<qint64> stored
|
||||
= {50, 51, 1332, 1333, 1334, 1335, 1336, 1337};
|
||||
const QList<qint64> storedNegative
|
||||
= {-50, 205, -1332, 64203, -1334, 4294965961, -1336, 4294965959};
|
||||
const QList<QList<qint64>> storedShuffled = {
|
||||
{ -51, 204, -1333, 64202, -1335, 4294965960, -1337, 4294967245 },
|
||||
{ -52, 203, -1334, 64201, -1336, 4294965959, -51, 4294967244 },
|
||||
{ -53, 202, -1335, 64200, -1337, 4294967245, -52, 4294967243 },
|
||||
{ -54, 201, -1336, 64199, -51, 4294967244, -53, 4294967242 },
|
||||
{ -55, 200, -1337, 65485, -52, 4294967243, -54, 4294967241 },
|
||||
{ -56, 199, -51, 65484, -53, 4294967242, -55, 4294967240 },
|
||||
{ -57, 205, -52, 65483, -54, 4294967241, -56, 4294967239 },
|
||||
{ -51, 204, -53, 65482, -55, 4294967240, -57, 4294967245 },
|
||||
};
|
||||
|
||||
QStringList asStrings(8);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
|
@ -3072,20 +3101,56 @@ void tst_QmlCppCodegen::numbersInJsPrimitive()
|
|||
QCOMPARE(asStrings, convertToStrings(zeroes));
|
||||
|
||||
QMetaObject::invokeMethod(o.data(), "writeValues");
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
}
|
||||
QCOMPARE(asStrings, convertToStrings(written));
|
||||
|
||||
QMetaObject::invokeMethod(o.data(), "negateValues");
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
}
|
||||
QCOMPARE(asStrings, convertToStrings(writtenNegative));
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(o.data(), "shuffleValues");
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
}
|
||||
QCOMPARE(asStrings, convertToStrings(writtenShuffled[i]));
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(o.data(), "storeValues");
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
}
|
||||
QCOMPARE(asStrings, convertToStrings(stored));
|
||||
|
||||
QMetaObject::invokeMethod(o.data(), "negateValues");
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
}
|
||||
QCOMPARE(asStrings, convertToStrings(storedNegative));
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(o.data(), "shuffleValues");
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
QMetaObject::invokeMethod(
|
||||
o.data(), "readValueAsString",
|
||||
Q_RETURN_ARG(QString, asStrings[i]), Q_ARG(int, i));
|
||||
}
|
||||
QCOMPARE(asStrings, convertToStrings(storedShuffled[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::infinitiesToInt()
|
||||
|
|
Loading…
Reference in New Issue