aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljscodegenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmlcompiler/qqmljscodegenerator.cpp')
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index cd325ae971..4dcf2af294 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -382,8 +382,11 @@ void QQmlJSCodeGenerator::eliminateDeadStores()
QString QQmlJSCodeGenerator::errorReturnValue() const
{
- if (m_function->returnType)
- return conversion(m_typeResolver->voidType(), m_function->returnType, QString());
+ if (auto ret = m_function->returnType) {
+ return ret->accessSemantics() == QQmlJSScope::AccessSemantics::Reference
+ ? conversion(m_typeResolver->voidType(), ret, QString()) // produces nullptr
+ : ret->internalName() + u"()"_qs;
+ }
return QString();
}
@@ -586,8 +589,11 @@ void QQmlJSCodeGenerator::generate_LoadReg(int reg)
void QQmlJSCodeGenerator::generate_StoreReg(int reg)
{
INJECT_TRACE_INFO(generate_StoreReg);
-
Q_ASSERT(m_state.accumulatorIn.isValid());
+
+ if (isArgument(reg))
+ reject(u"writing into a function argument"_qs);
+
const QString var = registerVariable(reg);
m_body.setWriteRegister(var);
if (var.isEmpty())
@@ -812,6 +818,15 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
const QString baseName = use(registerVariable(base));
const QString indexName = use(m_state.accumulatorVariableIn);
+ const QString voidAssignment = u" "_qs + m_state.accumulatorVariableOut + u" = "_qs +
+ conversion(m_typeResolver->globalType(m_typeResolver->voidType()),
+ m_state.accumulatorOut, QString()) + u";\n"_qs;
+
+ if (!m_typeResolver->isIntegral(m_state.accumulatorIn)) {
+ m_body += u"if (!QJSNumberCoercion::isInteger("_qs + indexName + u"))\n"_qs
+ + voidAssignment
+ + u"else "_qs;
+ }
// Our QQmlListProperty only keeps plain QObject*.
const auto valueType = m_typeResolver->valueType(baseType);
const auto elementType = m_typeResolver->globalType(
@@ -824,9 +839,8 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
conversion(elementType, m_state.accumulatorOut,
baseName + u".at(&"_qs + baseName + u", "_qs
+ indexName + u')') + u";\n"_qs;
- m_body += u"else\n"_qs;
- m_body += u" "_qs + m_state.accumulatorVariableOut + u" = {}"_qs;
- m_body += u";\n"_qs;
+ m_body += u"else\n"_qs
+ + voidAssignment;
}
void QQmlJSCodeGenerator::generate_StoreElement(int base, int index)
@@ -837,6 +851,7 @@ void QQmlJSCodeGenerator::generate_StoreElement(int base, int index)
m_body.setWriteRegister(QString());
const QQmlJSRegisterContent baseType = registerType(base);
+ const QQmlJSRegisterContent indexType = registerType(index);
if (!m_typeResolver->isNumeric(registerType(index)) || !baseType.isList()) {
reject(u"StoreElement with non-list base type or non-numeric arguments"_qs);
@@ -855,8 +870,11 @@ void QQmlJSCodeGenerator::generate_StoreElement(int base, int index)
const auto elementType = m_typeResolver->globalType(m_typeResolver->genericType(
m_typeResolver->containedType(valueType)));
- m_body += u"if ("_qs + indexName + u" >= 0 && "_qs + indexName
- + u" < "_qs + baseName + u".count(&"_qs + baseName
+ m_body += u"if ("_qs;
+ if (!m_typeResolver->isIntegral(indexType))
+ m_body += u"QJSNumberCoercion::isInteger("_qs + indexName + u") && "_qs;
+ m_body += indexName + u" >= 0 && "_qs
+ + indexName + u" < "_qs + baseName + u".count(&"_qs + baseName
+ u"))\n"_qs;
m_body += u" "_qs + baseName + u".replace(&"_qs + baseName
+ u", "_qs + indexName + u", "_qs;
@@ -1601,6 +1619,7 @@ void QQmlJSCodeGenerator::generate_ThrowException()
m_typeResolver->jsValueType()),
use(m_state.accumulatorVariableIn)) + u");\n"_qs;
m_body += u"return "_qs + errorReturnValue() + u";\n"_qs;
+ m_skipUntilNextLabel = true;
}
void QQmlJSCodeGenerator::generate_GetException()