diff --git a/js-assembler/runtime-src/baselib-functions.js b/js-assembler/runtime-src/baselib-functions.js index c6323b6..a7abd7d 100644 --- a/js-assembler/runtime-src/baselib-functions.js +++ b/js-assembler/runtime-src/baselib-functions.js @@ -196,8 +196,8 @@ MACHINE.p = oldProc; fail(e); }; - releaseLock(); - MACHINE.trampoline(v.label); + + MACHINE._trampoline(v.label, false, releaseLock); }); }; return f; @@ -225,85 +225,85 @@ // internallCallDuringPause: call a Racket procedure and get its results. - // The use assumes the machine is in a running-but-paused state. + // The use assumes the machine is in a running-but-paused state, where the + // lock is still in effect. The lock will continue to be in effect + // after coming back from the internal call. var internalCallDuringPause = function (MACHINE, proc, success, fail) { var args = []; var i; for (i = 0; i < arguments.length; i++) { args.push(arguments[i]); } - MACHINE.exclusiveLock.acquire( - "internal call during pause", - function(releaseLock) { - var i; - var oldArgcount, oldVal, oldProc, oldErrorHandler; - if (! baselib.arity.isArityMatching(proc.racketArity, args.length - 4)) { - var msg = baselib.format.format("arity mismatch: ~s expected ~s arguments, but received ~s", - [proc.displayName, proc.racketArity, args.length - 4]); - releaseLock(); - fail(baselib.exceptions.makeExnFailContractArity(msg, - MACHINE.captureContinuationMarks())); - } - if (isClosure(proc)) { - oldVal = MACHINE.v; - oldArgcount = MACHINE.a; - oldProc = MACHINE.p; + var i; + var oldArgcount, oldVal, oldProc, oldErrorHandler; + if (! baselib.arity.isArityMatching(proc.racketArity, args.length - 4)) { + var msg = baselib.format.format("arity mismatch: ~s expected ~s arguments, but received ~s", + [proc.displayName, proc.racketArity, args.length - 4]); + fail(baselib.exceptions.makeExnFailContractArity(msg, + MACHINE.captureContinuationMarks())); + } - oldErrorHandler = MACHINE.params['currentErrorHandler']; - var afterGoodInvoke = function (MACHINE) { - plt.runtime.PAUSE(function (restart) { - MACHINE.params['currentErrorHandler'] = oldErrorHandler; - var returnValue = MACHINE.v; - MACHINE.v = oldVal; - MACHINE.a = oldArgcount; - MACHINE.p = oldProc; - success(returnValue); - }); - }; - afterGoodInvoke.mvr = function (MACHINE) { - plt.runtime.PAUSE(function (restart) { - MACHINE.params['currentErrorHandler'] = oldErrorHandler; - var returnValues = [MACHINE.v]; - var i; - for (i = 0; i < MACHINE.a - 1; i++) { - returnValues.push(MACHINE.e.pop()); - } - MACHINE.v = oldVal; - MACHINE.a = oldArgcount; - MACHINE.p = oldProc; - success.apply(null, returnValues); - }); - }; + if (! isClosure(proc)) { + fail(baselib.exceptions.makeExnFail( + baselib.format.format( + "Not a procedure: ~e", + proc), + MACHINE.captureContinuationMarks())); - MACHINE.c.push( - new baselib.frames.CallFrame(afterGoodInvoke, proc)); - MACHINE.a = args.length - 4; - for (i = 0; i < args.length - 4; i++) { - MACHINE.e.push(args[args.length - 1 - i]); - } - MACHINE.p = proc; - MACHINE.params['currentErrorHandler'] = function (MACHINE, e) { - MACHINE.params['currentErrorHandler'] = oldErrorHandler; - MACHINE.v = oldVal; - MACHINE.a = oldArgcount; - MACHINE.p = oldProc; - fail(e); - }; - releaseLock(); - MACHINE.trampoline(proc.label); - - } else { - releaseLock(); - fail(baselib.exceptions.makeExnFail( - baselib.format.format( - "Not a procedure: ~e", - proc), - MACHINE.captureContinuationMarks())); - } + } + + oldVal = MACHINE.v; + oldArgcount = MACHINE.a; + oldProc = MACHINE.p; + + oldErrorHandler = MACHINE.params['currentErrorHandler']; + var afterGoodInvoke = function (MACHINE) { + plt.runtime.PAUSE(function (restart) { + MACHINE.params['currentErrorHandler'] = oldErrorHandler; + var returnValue = MACHINE.v; + MACHINE.v = oldVal; + MACHINE.a = oldArgcount; + MACHINE.p = oldProc; + success(returnValue); }); - }; + }; + afterGoodInvoke.mvr = function (MACHINE) { + plt.runtime.PAUSE(function (restart) { + MACHINE.params['currentErrorHandler'] = oldErrorHandler; + var returnValues = [MACHINE.v]; + var i; + for (i = 0; i < MACHINE.a - 1; i++) { + returnValues.push(MACHINE.e.pop()); + } + MACHINE.v = oldVal; + MACHINE.a = oldArgcount; + MACHINE.p = oldProc; + success.apply(null, returnValues); + }); + }; + MACHINE.c.push( + new baselib.frames.CallFrame(afterGoodInvoke, proc)); + MACHINE.a = args.length - 4; + for (i = 0; i < args.length - 4; i++) { + MACHINE.e.push(args[args.length - 1 - i]); + } + MACHINE.p = proc; + MACHINE.params['currentErrorHandler'] = function (MACHINE, e) { + MACHINE.params['currentErrorHandler'] = oldErrorHandler; + MACHINE.v = oldVal; + MACHINE.a = oldArgcount; + MACHINE.p = oldProc; + fail(e); + }; + MACHINE._trampoline(proc.label, + false, + function() { + // The lock should still being held, so we don't + // automatically unlock control. + }); + }; diff --git a/js-assembler/runtime-src/baselib-modules.js b/js-assembler/runtime-src/baselib-modules.js index 15aa6af..b005891 100644 --- a/js-assembler/runtime-src/baselib-modules.js +++ b/js-assembler/runtime-src/baselib-modules.js @@ -62,19 +62,28 @@ if (this.isInvoked) { succ(); } else { - MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) { - MACHINE.params['currentErrorHandler'] = oldErrorHandler; - fail(MACHINE, anError); - }; - MACHINE.c.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null)); if (isInternal) { + MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) { + MACHINE.params['currentErrorHandler'] = oldErrorHandler; + fail(MACHINE, anError); + }; + MACHINE.c.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null)); throw that.label; } else { - MACHINE.trampoline(that.label); + MACHINE.exclusiveLock.acquire( + undefined, + function(release) { + MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) { + MACHINE.params['currentErrorHandler'] = oldErrorHandler; + fail(MACHINE, anError); + }; + MACHINE.c.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null)); + MACHINE._trampoline(that.label, false, release); + }); } } }; - + exports.ModuleRecord = ModuleRecord; diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index 7f1b403..3863fe9 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -447,15 +447,10 @@ // var recomputeMaxNumBouncesBeforeYield; - var scheduleTrampoline = function(MACHINE, f, before) { + var scheduleTrampoline = function(MACHINE, f, release) { setTimeout( function() { - MACHINE.exclusiveLock.acquire( - 'scheduleTrampoline', - function(release) { - if (before) { before(); } - MACHINE._trampoline(f, false, release); - }); + MACHINE._trampoline(f, false, release); }, 0); }; @@ -463,18 +458,11 @@ // Creates a restarting function, that reschedules f in a context // with the old argcount in place. // Meant to be used only by the trampoline. - var makeRestartFunction = function(MACHINE) { + var makeRestartFunction = function(MACHINE, release) { var oldArgcount = MACHINE.a; - var oldEnv = MACHINE.e.slice(); - var oldControl = MACHINE.c.slice(); return function(f) { - MACHINE.exclusiveLock.acquire(undefined, - function(release) { - MACHINE.a = oldArgcount; - MACHINE.e = oldEnv; - MACHINE.c = oldControl; - MACHINE._trampoline(f, false, release); - }); + MACHINE.a = oldArgcount; + MACHINE._trampoline(f, false, release); }; }; @@ -563,14 +551,12 @@ recomputeMaxNumBouncesBeforeYield( that, (new Date()).valueOf() - startTime); - scheduleTrampoline(that, thunk); - release(); + scheduleTrampoline(that, thunk, release); return; } } else if (e instanceof Pause) { - var restart = makeRestartFunction(that); + var restart = makeRestartFunction(that, release); e.onPause(restart); - release(); return; } else if (e instanceof HaltError) { that.running = false;