diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2022-11-03 17:09:29 +0100 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-11-07 15:49:10 +0100 |
| commit | 872e91612fd83de6dd1193014b5e2a0f5e8c30af (patch) | |
| tree | 98eb22f6203a5b8f81e4149f919cac0f553c202c /src/qml/compiler/qv4codegen.cpp | |
| parent | 0b7374fefa1abf08e956bc5d34008352144bd9ae (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.cpp | 25 |
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: |
