diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js index 28737b361..285b241ab 100644 --- a/src/blocks/scratch3_control.js +++ b/src/blocks/scratch3_control.js @@ -110,7 +110,7 @@ Scratch3ControlBlocks.prototype.stop = function (args, util) { option === 'other scripts in stage') { util.stopOtherTargetThreads(); } else if (option === 'this script') { - util.stopThread(); + util.stopThisScript(); } }; diff --git a/src/engine/execute.js b/src/engine/execute.js index 44951aba3..226a866a7 100644 --- a/src/engine/execute.js +++ b/src/engine/execute.js @@ -183,8 +183,8 @@ var execute = function (sequencer, thread) { stopOtherTargetThreads: function () { runtime.stopForTarget(target, thread); }, - stopThread: function () { - sequencer.retireThread(thread); + stopThisScript: function () { + thread.stopThisScript(); }, startProcedure: function (procedureCode) { sequencer.stepToProcedure(thread, procedureCode); diff --git a/src/engine/thread.js b/src/engine/thread.js index 9693b26f1..f093f886e 100644 --- a/src/engine/thread.js +++ b/src/engine/thread.js @@ -140,6 +140,27 @@ Thread.prototype.popStack = function () { return this.stack.pop(); }; +/** + * Pop back down the stack frame until we hit a procedure call or the stack frame is emptied + */ +Thread.prototype.stopThisScript = function () { + var blockID = this.peekStack(); + while (blockID !== null) { + var block = this.target.blocks.getBlock(blockID); + if (typeof block !== 'undefined' && block.opcode === 'procedures_callnoreturn') { + break; + } + this.popStack(); + blockID = this.peekStack(); + } + + if (this.stack.length === 0) { + // Clean up! + this.requestScriptGlowInFrame = false; + this.status = Thread.STATUS_DONE; + } +}; + /** * Get top stack item. * @return {?string} Block ID on top of stack. diff --git a/test/unit/blocks_control.js b/test/unit/blocks_control.js index 2dc6049df..7867524ce 100644 --- a/test/unit/blocks_control.js +++ b/test/unit/blocks_control.js @@ -104,7 +104,7 @@ test('stop', function (t) { var state = { stopAll: 0, stopOtherTargetThreads: 0, - stopThread: 0 + stopThisScript: 0 }; var util = { stopAll: function () { @@ -113,8 +113,8 @@ test('stop', function (t) { stopOtherTargetThreads: function () { state.stopOtherTargetThreads++; }, - stopThread: function () { - state.stopThread++; + stopThisScript: function () { + state.stopThisScript++; } }; @@ -125,6 +125,6 @@ test('stop', function (t) { c.stop({STOP_OPTION: 'this script'}, util); t.strictEqual(state.stopAll, 1); t.strictEqual(state.stopOtherTargetThreads, 2); - t.strictEqual(state.stopThread, 1); + t.strictEqual(state.stopThisScript, 1); t.end(); });