diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-07-26 15:25:08 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-08-09 16:53:44 +0200 |
commit | dd86881520dde6c1487e5397f10b82584e6b9eaa (patch) | |
tree | 6cbcb2685eeded05b2068d5177db9d6a25b3522d /src/qml/compiler | |
parent | 35f948a1add8a46d85c6383971e9ebff3e0dada7 (diff) |
QQmlIRBuilder: Always preserve "undefined" string
QQmlIRBuilder skips storing binding scripts as a string to save memory.
However, for QQmlScriptString, we need the string to be available. This
is solved by running QQmlScriptStringScanner in the type compiler at
runtime, which sets the correct stringIndex for script string bindings.
However, that one does not run when we already have a compilation unit
from cachegen (and if we would run it unconditionally, we still would
miss the source code to recover the string).
We work around this issue by noting that QQmlScriptString only cares
about a very limited set of strings: Namely the various literals and
undefined. The literals are already correctly handled, as IRBuilder has
specific optimizations for them anyway. We now check in the generic case
whether the bindings string equals "undefined", and if so, ensure that
the string is registered.
Fixes: QTBUG-91165
Pick-to: 6.2
Change-Id: I4c4696952a082d1e69e0c9e5a0b9bf2470d59187
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 2dbf288cd3..29cb8e33d7 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1172,7 +1172,15 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST binding->value.compiledScriptIndex = index; // We don't need to store the binding script as string, except for script strings // and types with custom parsers. Those will be added later in the compilation phase. - binding->stringIndex = emptyStringIndex; + // Except that we cannot recover the string when cachegen runs; we need to therefore retain + // "undefined". Any other "special" strings (for the various literals) are already handled above + QQmlJS::AST::Node *nodeForString = statement; + if (exprStmt) + nodeForString = exprStmt->expression; + if (asStringRef(nodeForString) == u"undefined") + binding->stringIndex = registerString(u"undefined"_qs); + else + binding->stringIndex = emptyStringIndex; } } |