Skip to content

Commit 43677b9

Browse files
authored
Merge pull request #273 from scratchcpp/fix_self_calling_broadcast_crash
Fix #256: Fix self calling broadcast crash
2 parents 4cd26f7 + b4a40e7 commit 43677b9

File tree

5 files changed

+59
-4
lines changed

5 files changed

+59
-4
lines changed

src/engine/virtualmachine.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,26 @@ void VirtualMachine::replaceReturnValue(const Value &v, unsigned int offset)
164164
/*! Continues running the script from last position (the first instruction is skipped). */
165165
void VirtualMachine::run()
166166
{
167+
impl->running = true;
168+
167169
unsigned int *ret = impl->run(impl->pos);
168170
assert(ret);
171+
169172
if (impl->savePos)
170173
impl->pos = ret;
174+
175+
impl->running = false;
171176
}
172177

173178
/*! Jumps back to the initial position. */
174179
void VirtualMachine::reset()
175180
{
176181
assert(impl->bytecode);
177182
impl->pos = impl->bytecode;
178-
impl->regCount = 0;
183+
impl->atEnd = false;
184+
185+
if (!impl->running) // Registers will be freed when the script stops running
186+
impl->regCount = 0;
179187
}
180188

181189
/*! Moves back to the last vm::OP_CHECKPOINT instruction in the bytecode. */

src/engine/virtualmachine_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct VirtualMachinePrivate
4343
Script *script = nullptr;
4444
unsigned int *pos = nullptr;
4545
unsigned int *checkpoint = nullptr;
46+
bool running = false;
4647
bool atEnd = false;
4748
std::vector<Loop> loops;
4849
std::vector<unsigned int *> callTree;

test/engine/engine_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,11 @@ TEST(EngineTest, NoCrashAfterStop)
614614
ASSERT_TRUE(p.load());
615615
p.run();
616616
}
617+
618+
TEST(EngineTest, NoCrashOnBroadcastSelfCall)
619+
{
620+
// Regtest for #256
621+
Project p("regtest_projects/256_broadcast_self_call_crash.sb3");
622+
ASSERT_TRUE(p.load());
623+
p.run();
624+
}
1.23 KB
Binary file not shown.

test/virtual_machine/virtual_machine_test.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,21 @@ unsigned int testFunction5(VirtualMachine *vm)
13271327
return 0;
13281328
}
13291329

1330+
unsigned int testFunction6(VirtualMachine *vm)
1331+
{
1332+
vm->addReturnValue(0);
1333+
vm->stop(true, false, false);
1334+
return 1;
1335+
}
1336+
1337+
unsigned int testFunction7(VirtualMachine *vm)
1338+
{
1339+
vm->addReturnValue(0);
1340+
vm->stop(true, false, false);
1341+
vm->reset();
1342+
return 1;
1343+
}
1344+
13301345
TEST(VirtualMachineTest, OP_EXEC)
13311346
{
13321347
static unsigned int bytecode[] = {
@@ -1518,18 +1533,41 @@ TEST(VirtualMachineTest, OP_WARP)
15181533

15191534
TEST(VirtualMachineTest, Reset)
15201535
{
1521-
static unsigned int bytecode[] = { OP_START, OP_NULL, OP_EXEC, 0, OP_HALT };
1522-
static BlockFunc functions[] = { &testFunction3 };
1536+
static unsigned int bytecode1[] = { OP_START, OP_NULL, OP_EXEC, 0, OP_HALT };
1537+
static unsigned int bytecode2[] = { OP_START, OP_NULL, OP_EXEC, 1, OP_HALT };
1538+
static BlockFunc functions[] = { &testFunction6, &testFunction7 };
15231539

15241540
VirtualMachine vm;
1525-
vm.setBytecode(bytecode);
1541+
vm.setBytecode(bytecode1);
15261542
vm.setFunctions(functions);
1543+
15271544
vm.run();
15281545
ASSERT_FALSE(vm.atEnd());
1546+
ASSERT_EQ(vm.registerCount(), 1);
15291547
vm.reset();
1548+
ASSERT_EQ(vm.registerCount(), 0);
15301549
ASSERT_FALSE(vm.atEnd());
15311550
vm.run();
15321551
ASSERT_FALSE(vm.atEnd());
15331552
vm.run();
15341553
ASSERT_TRUE(vm.atEnd());
1554+
1555+
vm.reset();
1556+
ASSERT_FALSE(vm.atEnd());
1557+
1558+
vm.setBytecode(bytecode2);
1559+
1560+
vm.run();
1561+
ASSERT_FALSE(vm.atEnd());
1562+
ASSERT_EQ(vm.registerCount(), 1);
1563+
vm.reset();
1564+
ASSERT_EQ(vm.registerCount(), 0);
1565+
ASSERT_FALSE(vm.atEnd());
1566+
vm.run();
1567+
ASSERT_FALSE(vm.atEnd());
1568+
vm.run();
1569+
ASSERT_TRUE(vm.atEnd());
1570+
1571+
vm.reset();
1572+
ASSERT_FALSE(vm.atEnd());
15351573
}

0 commit comments

Comments
 (0)