From 1590f63136b8bc1bcb2037ef5f2c3eec586e4e45 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 22 Dec 2023 13:36:46 +0100 Subject: [PATCH] fix #387: Do not clear procedure arguments when stopping the VM --- src/engine/virtualmachine_p.cpp | 4 --- test/virtual_machine/virtual_machine_test.cpp | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/engine/virtualmachine_p.cpp b/src/engine/virtualmachine_p.cpp index a1ac3242..8215234a 100644 --- a/src/engine/virtualmachine_p.cpp +++ b/src/engine/virtualmachine_p.cpp @@ -731,10 +731,6 @@ do_exec : { } if (stop) { stop = false; - callTree.clear(); - procedureArgTree.clear(); - procedureArgs = nullptr; - nextProcedureArgs = nullptr; if (goBack) { goBack = false; pos -= instruction_arg_count[OP_EXEC] + 1; diff --git a/test/virtual_machine/virtual_machine_test.cpp b/test/virtual_machine/virtual_machine_test.cpp index a1df4f3f..5993b6c1 100644 --- a/test/virtual_machine/virtual_machine_test.cpp +++ b/test/virtual_machine/virtual_machine_test.cpp @@ -1659,3 +1659,31 @@ TEST(VirtualMachineTest, NoCrashInNestedLoopsInIfElseStatements) vm.run(); ASSERT_EQ(vm.registerCount(), 0); } + +TEST(VirtualMachineTest, NoCrashWhenReadingProcedureArgsAfterStopping) +{ + // Regtest for #387 + static unsigned int bytecode[] = { OP_START, OP_INIT_PROCEDURE, OP_CONST, 0, OP_ADD_ARG, OP_CALL_PROCEDURE, 0, OP_HALT }; + static unsigned int procedure[] = { OP_START, OP_NULL, OP_EXEC, 0, OP_READ_ARG, 0, OP_PRINT, OP_HALT }; + static unsigned int *procedures[] = { procedure }; + static BlockFunc functions[] = { &testFunction3 }; + static Value constValues[] = { "test" }; + + VirtualMachine vm(nullptr, nullptr, nullptr); + vm.setBytecode(bytecode); + vm.setProcedures(procedures); + vm.setFunctions(functions); + vm.setConstValues(constValues); + + testing::internal::CaptureStdout(); + vm.run(); + ASSERT_TRUE(testing::internal::GetCapturedStdout().empty()); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_FALSE(vm.atEnd()); + + testing::internal::CaptureStdout(); + vm.run(); + ASSERT_EQ(testing::internal::GetCapturedStdout(), "test\n"); + ASSERT_EQ(vm.registerCount(), 0); + ASSERT_TRUE(vm.atEnd()); +}