From 362a2312796e4fda1a3201241c5de671a2c86e5a Mon Sep 17 00:00:00 2001 From: griffpatch Date: Mon, 20 Feb 2017 08:20:21 +0000 Subject: [PATCH 1/2] bug - escape from conditional branches Execution bug: can't escape from conditional branches that end with a Promise-resolution-terminating command block (see #464) --- src/engine/execute.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/engine/execute.js b/src/engine/execute.js index 226a866a76..5d2734dde5 100644 --- a/src/engine/execute.js +++ b/src/engine/execute.js @@ -233,8 +233,15 @@ var execute = function (sequencer, thread) { primitiveReportedValue.then(function (resolvedValue) { handleReport(resolvedValue); if (typeof resolvedValue === 'undefined') { - var popped = thread.popStack(); - var nextBlockId = thread.target.blocks.getNextBlock(popped); + do { + // In the case that the promise is the last block in the current thread stack + // We need to pop out repeatedly until we find the next block. + var popped = thread.popStack(); + if (popped === null) { + return; + } + var nextBlockId = thread.target.blocks.getNextBlock(popped); + } while (nextBlockId === null); thread.pushStack(nextBlockId); } else { thread.popStack(); From c5eb8ece1628cf0d142b27d76238a8551f6f40de Mon Sep 17 00:00:00 2001 From: griffpatch Date: Mon, 20 Feb 2017 09:40:32 +0000 Subject: [PATCH 2/2] Handle actual looping cases And it starts to get a little less elegant :/ Wondering if this should not be handled better in another part of the codebase? We don't want to be duplicating existing code stepping functionality locally at the end of the promise script really... What do you think? --- src/engine/execute.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/engine/execute.js b/src/engine/execute.js index 5d2734dde5..7ff0203ecb 100644 --- a/src/engine/execute.js +++ b/src/engine/execute.js @@ -241,7 +241,15 @@ var execute = function (sequencer, thread) { return; } var nextBlockId = thread.target.blocks.getNextBlock(popped); - } while (nextBlockId === null); + if (nextBlockId !== null) { + // A next block exists so break out this loop + break; + } + // Investigate the next block and if not in a loop, + // then repeat and pop the next item off the stack frame + var stackFrame = thread.peekStackFrame(); + } while (stackFrame !== null && !stackFrame.isLoop); + thread.pushStack(nextBlockId); } else { thread.popStack();