aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compiler.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-08-11 15:47:13 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-08-17 19:04:40 +0000
commit4d391ad2968efccf0ec5f2840126f051b40a89f9 (patch)
tree22ce9ea4c60e23f3de94432a97a11c2a66b219ff /src/qml/compiler/qv4compiler.cpp
parentfcdd613dbeb9945604f15c164b4c97aba4f195a0 (diff)
When binding signals, run the outer function to get the nested one
The outer function may perform important tasks like setting up a call context with a "this" member for the nested function. In particular, arrow functions retain their original "this" member, no matter where they are executed later. We can detect this condition while generating the compilation unit. If the outer function is not a simple wrapper that only returns the inner function, execute it when binding a signal. Fixes: QTBUG-95659 Change-Id: I7dfef2c78378588e6bfc4bedde7889c7f2ce03ef Reviewed-by: Yuya Nishihara <yuya.nishihara@qt.io> Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io> (cherry picked from commit 8cd7aabfb24b391143b3c358f49fb6a28765d5f3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/qml/compiler/qv4compiler.cpp')
-rw-r--r--src/qml/compiler/qv4compiler.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 5511ed304a..02e2470850 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -432,9 +432,21 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
function->flags |= CompiledData::Function::IsArrowFunction;
if (irFunction->isGenerator)
function->flags |= CompiledData::Function::IsGenerator;
- function->nestedFunctionIndex =
- irFunction->returnsClosure ? quint32(module->functions.indexOf(irFunction->nestedContexts.first()))
- : std::numeric_limits<uint32_t>::max();
+ if (irFunction->returnsClosure)
+ function->flags |= CompiledData::Function::IsClosureWrapper;
+
+ if (!irFunction->returnsClosure
+ || irFunction->innerFunctionAccessesThis
+ || irFunction->innerFunctionAccessesNewTarget) {
+ // If the inner function does things with this and new.target we need to do some work in
+ // the outer function. Then we shouldn't directly access the nested function.
+ function->nestedFunctionIndex = std::numeric_limits<uint32_t>::max();
+ } else {
+ // Otherwise we can directly use the nested function.
+ function->nestedFunctionIndex
+ = quint32(module->functions.indexOf(irFunction->nestedContexts.first()));
+ }
+
function->length = irFunction->formals ? irFunction->formals->length() : 0;
function->nFormals = irFunction->arguments.size();
function->formalsOffset = currentOffset;