aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-11-03 17:09:29 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-11-07 15:49:10 +0100
commit872e91612fd83de6dd1193014b5e2a0f5e8c30af (patch)
tree98eb22f6203a5b8f81e4149f919cac0f553c202c /src/qml/compiler/qv4codegen.cpp
parent0b7374fefa1abf08e956bc5d34008352144bd9ae (diff)
Replace CallElement with separate instructions
We need to do the subscript lookup before generating the arguments since the arguments may change the array. Fixes: QTBUG-106708 Change-Id: Ia3a0dd34c6ed8d39e86ad20911a632d691826322 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 6f8e572702..5851ca3827 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1908,6 +1908,17 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
return Reference();
}
+Codegen::Reference Codegen::loadSubscriptForCall(const Codegen::Reference &base)
+{
+ // Retrieve the function to be called before generating the arguments.
+ // Generating the arguments might change the array.
+ base.elementSubscript.loadInAccumulator();
+ Codegen::Instruction::LoadElement load;
+ load.base = base.elementBase;
+ bytecodeGenerator->addInstruction(load);
+ return Reference::fromAccumulator(this);
+}
+
bool Codegen::visit(CallExpression *ast)
{
if (hasError())
@@ -1924,9 +1935,11 @@ bool Codegen::visit(CallExpression *ast)
return false;
switch (base.type) {
case Reference::Member:
- case Reference::Subscript:
base = base.asLValue();
break;
+ case Reference::Subscript:
+ base.element = loadSubscriptForCall(base).storeOnStack().stackSlot();
+ break;
case Reference::Name:
break;
case Reference::Super:
@@ -2034,9 +2047,9 @@ void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunctio
bytecodeGenerator->addInstruction(call);
}
} else if (base.type == Reference::Subscript) {
- Instruction::CallElement call;
- call.base = base.elementBase;
- call.index = base.elementSubscript.stackSlot();
+ Instruction::CallWithReceiver call;
+ call.thisObject = base.elementBase.stackSlot();
+ call.name = base.element;
call.argc = calldata.argc;
call.argv = calldata.argv;
bytecodeGenerator->addInstruction(call);
@@ -2480,9 +2493,11 @@ bool Codegen::handleTaggedTemplate(Reference base, TaggedTemplate *ast)
int functionObject = -1, thisObject = -1;
switch (base.type) {
case Reference::Member:
- case Reference::Subscript:
base = base.asLValue();
break;
+ case Reference::Subscript:
+ base.element = loadSubscriptForCall(base).storeOnStack().stackSlot();
+ break;
case Reference::Name:
break;
case Reference::SuperProperty: