summaryrefslogtreecommitdiff
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-11-15 16:26:49 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-11-22 12:32:16 +0100
commit8f827de1a1cc466f4c99049a90669f1c538e717f (patch)
treea8d047a5b4e3012bb4d41b4a63e850c41f11aa00 /src/qml/compiler/qv4codegen.cpp
parentcff3977d2ec5e55d0285e13b2bfe31ca04babf66 (diff)
downloadqtdeclarative-8f827de1a1cc466f4c99049a90669f1c538e717f.tar.gz
QML: Do not crash on CallWithSpread
We need to check for subscripts also when creating CallWithSpread and TailCall instructions. Furthermore, the == operator of Reference needs to take into account whether the subscript has been loaded or not. Amends commit 872e91612fd83de6dd1193014b5e2a0f5e8c30af. Fixes: QTBUG-108441 Change-Id: I2d1a7a11f9cdcb4320a87df979d9ca4457620d3f Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 1ce5f9118c..157f831bb8 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1961,6 +1961,7 @@ bool Codegen::visit(CallExpression *ast)
break;
case Reference::Subscript:
base.element = loadSubscriptForCall(base).storeOnStack().stackSlot();
+ base.subscriptLoadedForCall = true;
break;
case Reference::Name:
break;
@@ -2002,21 +2003,29 @@ bool Codegen::visit(CallExpression *ast)
baseObject.storeOnStack(thisObject);
baseObject = Reference::fromStackSlot(this, thisObject);
}
- if (!base.isStackSlot()) {
- base.storeOnStack(functionObject);
- base = Reference::fromStackSlot(this, functionObject);
- }
+
+ const int func = [&]() {
+ if (base.type == Reference::Subscript)
+ return base.element;
+
+ if (!base.isStackSlot()) {
+ base.storeOnStack(functionObject);
+ base = Reference::fromStackSlot(this, functionObject);
+ }
+
+ return base.stackSlot();
+ }();
if (calldata.hasSpread) {
Instruction::CallWithSpread call;
- call.func = base.stackSlot();
+ call.func = func;
call.thisObject = baseObject.stackSlot();
call.argc = calldata.argc;
call.argv = calldata.argv;
bytecodeGenerator->addInstruction(call);
} else {
Instruction::TailCall call;
- call.func = base.stackSlot();
+ call.func = func;
call.thisObject = baseObject.stackSlot();
call.argc = calldata.argc;
call.argv = calldata.argv;
@@ -2521,6 +2530,7 @@ bool Codegen::handleTaggedTemplate(Reference base, TaggedTemplate *ast)
break;
case Reference::Subscript:
base.element = loadSubscriptForCall(base).storeOnStack().stackSlot();
+ base.subscriptLoadedForCall = true;
break;
case Reference::Name:
break;
@@ -4322,7 +4332,9 @@ bool Codegen::Reference::operator==(const Codegen::Reference &other) const
case Member:
return propertyBase == other.propertyBase && propertyNameIndex == other.propertyNameIndex;
case Subscript:
- return elementBase == other.elementBase && elementSubscript == other.elementSubscript;
+ return elementBase == other.elementBase && other.subscriptLoadedForCall
+ ? (subscriptLoadedForCall && element == other.element)
+ : (!subscriptLoadedForCall && elementSubscript == other.elementSubscript);
case Import:
return index == other.index;
case Const: