diff --git a/whalesong/js-assembler/assemble.rkt b/whalesong/js-assembler/assemble.rkt index df85e63..589deee 100644 --- a/whalesong/js-assembler/assemble.rkt +++ b/whalesong/js-assembler/assemble.rkt @@ -583,7 +583,7 @@ EOF (assemble-label (make-Label (LinkedLabel-label label)))])))] [(PushControlFrame/Prompt? stmt) - (format "M.c.push(new RT.CallFrame(~a,M.p)); M.addPrompt(~a,false);" + (format "M.c.push(new RT.CallFrame(~a,M.p)); M.addPrompt(~a,false,M.e.length);" (let: ([label : (U Symbol LinkedLabel) (PushControlFrame/Prompt-label stmt)]) (cond [(symbol? label) diff --git a/whalesong/js-assembler/runtime-src/baselib-primitives.js b/whalesong/js-assembler/runtime-src/baselib-primitives.js index e77c449..7fa2800 100644 --- a/whalesong/js-assembler/runtime-src/baselib-primitives.js +++ b/whalesong/js-assembler/runtime-src/baselib-primitives.js @@ -3177,7 +3177,7 @@ M.e.pop(); M.p = proc; M.a = 0; - M.addPrompt(promptTag, false); + M.addPrompt(promptTag, false, M.e.length); baselib.functions.rawApply(M); }, []); @@ -3272,13 +3272,17 @@ handler = makeDefaultPromptHandler(promptTag); } } - M.p = proc; if (M.a >= 1) { M.e.pop(); } // the test is redundant, but I want the parallelism. if (M.a >= 2) { M.e.pop(); } if (M.a >= 3) { M.e.pop(); } M.a = Math.max(M.a - 3, 0); - M.addPrompt(promptTag, handler); + + // subtle: the prompt's environment is the one _after_ the current call! + // That's why we need to do M.e.length - M.a: the environment currently + // has extra values due to us calling the prompt handler here. + M.addPrompt(promptTag, handler, M.e.length - M.a); + baselib.functions.rawApply(M); }); diff --git a/whalesong/js-assembler/runtime-src/runtime.js b/whalesong/js-assembler/runtime-src/runtime.js index b217258..e976436 100644 --- a/whalesong/js-assembler/runtime-src/runtime.js +++ b/whalesong/js-assembler/runtime-src/runtime.js @@ -499,10 +499,11 @@ M.c.pop(); return(M.p.mvr)(M); }; - Machine.prototype.addPrompt = function(promptTag, abortHandlerClosure) { + + Machine.prototype.addPrompt = function(promptTag, abortHandlerClosure, envLength) { this.c.push(new PromptFrame(justReturn, promptTag, - this.e.length, + envLength, abortHandlerClosure)); };