From f0fc968e78058534ded3ba47d3ec5e3e13372dc1 Mon Sep 17 00:00:00 2001 From: Alex Cui Date: Thu, 27 Aug 2026 00:33:41 +0800 Subject: [PATCH 1/2] fix(vm): thread status check after executing hats --- packages/scratch-vm/src/engine/runtime.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/scratch-vm/src/engine/runtime.js b/packages/scratch-vm/src/engine/runtime.js index 85ee4ae9452..407d625c187 100644 --- a/packages/scratch-vm/src/engine/runtime.js +++ b/packages/scratch-vm/src/engine/runtime.js @@ -1926,6 +1926,10 @@ class Runtime extends EventEmitter { // threads are stepped. See ScratchRuntime.as for original implementation newThreads.forEach(thread => { execute(this.sequencer, thread); + if (thread.status === Thread.STATUS_DONE) { + // Thread might be done after `execute`. + return; + } thread.goToNextBlock(); }); return newThreads; From 8fcddc1676741f2ac0e2e6696e4eb2dea5a8db01 Mon Sep 17 00:00:00 2001 From: Alex Cui Date: Thu, 27 Aug 2026 00:34:47 +0800 Subject: [PATCH 2/2] fix(vm): typo of thread.stackFrames in retireThread --- packages/scratch-vm/src/engine/sequencer.js | 2 +- packages/scratch-vm/src/engine/thread.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/scratch-vm/src/engine/sequencer.js b/packages/scratch-vm/src/engine/sequencer.js index d37a466de48..8972309bbf3 100644 --- a/packages/scratch-vm/src/engine/sequencer.js +++ b/packages/scratch-vm/src/engine/sequencer.js @@ -352,7 +352,7 @@ class Sequencer { */ retireThread (thread) { thread.stack = []; - thread.stackFrame = []; + thread.stackFrames = []; thread.requestScriptGlowInFrame = false; thread.status = Thread.STATUS_DONE; } diff --git a/packages/scratch-vm/src/engine/thread.js b/packages/scratch-vm/src/engine/thread.js index 5cc3e6a8480..2aaf35943e2 100644 --- a/packages/scratch-vm/src/engine/thread.js +++ b/packages/scratch-vm/src/engine/thread.js @@ -251,7 +251,7 @@ class Thread { /** * Reset the stack frame for use by the next block. * (avoids popping and re-pushing a new stack frame - keeps the warpmode the same - * @param {string} blockId Block ID to push to stack. + * @param {string | null} blockId Block ID to push to stack. */ reuseStackForNextBlock (blockId) { this.stack[this.stack.length - 1] = blockId;