Trying to introduce mechanism for locking the evaluator, but I'm still running into several messy issues.
This commit is contained in:
parent
23d4c27c2b
commit
4573dc701e
|
@ -196,8 +196,8 @@
|
||||||
MACHINE.p = oldProc;
|
MACHINE.p = oldProc;
|
||||||
fail(e);
|
fail(e);
|
||||||
};
|
};
|
||||||
releaseLock();
|
|
||||||
MACHINE.trampoline(v.label);
|
MACHINE._trampoline(v.label, false, releaseLock);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return f;
|
return f;
|
||||||
|
@ -225,27 +225,34 @@
|
||||||
|
|
||||||
|
|
||||||
// internallCallDuringPause: call a Racket procedure and get its results.
|
// 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 internalCallDuringPause = function (MACHINE, proc, success, fail) {
|
||||||
var args = [];
|
var args = [];
|
||||||
var i;
|
var i;
|
||||||
for (i = 0; i < arguments.length; i++) {
|
for (i = 0; i < arguments.length; i++) {
|
||||||
args.push(arguments[i]);
|
args.push(arguments[i]);
|
||||||
}
|
}
|
||||||
MACHINE.exclusiveLock.acquire(
|
|
||||||
"internal call during pause",
|
|
||||||
function(releaseLock) {
|
|
||||||
var i;
|
var i;
|
||||||
var oldArgcount, oldVal, oldProc, oldErrorHandler;
|
var oldArgcount, oldVal, oldProc, oldErrorHandler;
|
||||||
if (! baselib.arity.isArityMatching(proc.racketArity, args.length - 4)) {
|
if (! baselib.arity.isArityMatching(proc.racketArity, args.length - 4)) {
|
||||||
var msg = baselib.format.format("arity mismatch: ~s expected ~s arguments, but received ~s",
|
var msg = baselib.format.format("arity mismatch: ~s expected ~s arguments, but received ~s",
|
||||||
[proc.displayName, proc.racketArity, args.length - 4]);
|
[proc.displayName, proc.racketArity, args.length - 4]);
|
||||||
releaseLock();
|
|
||||||
fail(baselib.exceptions.makeExnFailContractArity(msg,
|
fail(baselib.exceptions.makeExnFailContractArity(msg,
|
||||||
MACHINE.captureContinuationMarks()));
|
MACHINE.captureContinuationMarks()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isClosure(proc)) {
|
if (! isClosure(proc)) {
|
||||||
|
fail(baselib.exceptions.makeExnFail(
|
||||||
|
baselib.format.format(
|
||||||
|
"Not a procedure: ~e",
|
||||||
|
proc),
|
||||||
|
MACHINE.captureContinuationMarks()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
oldVal = MACHINE.v;
|
oldVal = MACHINE.v;
|
||||||
oldArgcount = MACHINE.a;
|
oldArgcount = MACHINE.a;
|
||||||
oldProc = MACHINE.p;
|
oldProc = MACHINE.p;
|
||||||
|
@ -290,17 +297,11 @@
|
||||||
MACHINE.p = oldProc;
|
MACHINE.p = oldProc;
|
||||||
fail(e);
|
fail(e);
|
||||||
};
|
};
|
||||||
releaseLock();
|
MACHINE._trampoline(proc.label,
|
||||||
MACHINE.trampoline(proc.label);
|
false,
|
||||||
|
function() {
|
||||||
} else {
|
// The lock should still being held, so we don't
|
||||||
releaseLock();
|
// automatically unlock control.
|
||||||
fail(baselib.exceptions.makeExnFail(
|
|
||||||
baselib.format.format(
|
|
||||||
"Not a procedure: ~e",
|
|
||||||
proc),
|
|
||||||
MACHINE.captureContinuationMarks()));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -310,7 +311,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var makeClosure = function (name, arity, f, closureArgs) {
|
var makeClosure = function (name, arity, f, closureArgs) {
|
||||||
if (! closureArgs) { closureArgs = []; }
|
if (! closureArgs) { closureArgs = []; }
|
||||||
return new Closure(f,
|
return new Closure(f,
|
||||||
|
|
|
@ -62,15 +62,24 @@
|
||||||
if (this.isInvoked) {
|
if (this.isInvoked) {
|
||||||
succ();
|
succ();
|
||||||
} else {
|
} else {
|
||||||
|
if (isInternal) {
|
||||||
MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) {
|
MACHINE.params['currentErrorHandler'] = function (MACHINE, anError) {
|
||||||
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
MACHINE.params['currentErrorHandler'] = oldErrorHandler;
|
||||||
fail(MACHINE, anError);
|
fail(MACHINE, anError);
|
||||||
};
|
};
|
||||||
MACHINE.c.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
|
MACHINE.c.push(new plt.baselib.frames.CallFrame(afterGoodInvoke, null));
|
||||||
if (isInternal) {
|
|
||||||
throw that.label;
|
throw that.label;
|
||||||
} else {
|
} 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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -447,15 +447,10 @@
|
||||||
//
|
//
|
||||||
var recomputeMaxNumBouncesBeforeYield;
|
var recomputeMaxNumBouncesBeforeYield;
|
||||||
|
|
||||||
var scheduleTrampoline = function(MACHINE, f, before) {
|
var scheduleTrampoline = function(MACHINE, f, release) {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
function() {
|
function() {
|
||||||
MACHINE.exclusiveLock.acquire(
|
|
||||||
'scheduleTrampoline',
|
|
||||||
function(release) {
|
|
||||||
if (before) { before(); }
|
|
||||||
MACHINE._trampoline(f, false, release);
|
MACHINE._trampoline(f, false, release);
|
||||||
});
|
|
||||||
},
|
},
|
||||||
0);
|
0);
|
||||||
};
|
};
|
||||||
|
@ -463,18 +458,11 @@
|
||||||
// Creates a restarting function, that reschedules f in a context
|
// Creates a restarting function, that reschedules f in a context
|
||||||
// with the old argcount in place.
|
// with the old argcount in place.
|
||||||
// Meant to be used only by the trampoline.
|
// Meant to be used only by the trampoline.
|
||||||
var makeRestartFunction = function(MACHINE) {
|
var makeRestartFunction = function(MACHINE, release) {
|
||||||
var oldArgcount = MACHINE.a;
|
var oldArgcount = MACHINE.a;
|
||||||
var oldEnv = MACHINE.e.slice();
|
|
||||||
var oldControl = MACHINE.c.slice();
|
|
||||||
return function(f) {
|
return function(f) {
|
||||||
MACHINE.exclusiveLock.acquire(undefined,
|
|
||||||
function(release) {
|
|
||||||
MACHINE.a = oldArgcount;
|
MACHINE.a = oldArgcount;
|
||||||
MACHINE.e = oldEnv;
|
|
||||||
MACHINE.c = oldControl;
|
|
||||||
MACHINE._trampoline(f, false, release);
|
MACHINE._trampoline(f, false, release);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -563,14 +551,12 @@
|
||||||
recomputeMaxNumBouncesBeforeYield(
|
recomputeMaxNumBouncesBeforeYield(
|
||||||
that,
|
that,
|
||||||
(new Date()).valueOf() - startTime);
|
(new Date()).valueOf() - startTime);
|
||||||
scheduleTrampoline(that, thunk);
|
scheduleTrampoline(that, thunk, release);
|
||||||
release();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (e instanceof Pause) {
|
} else if (e instanceof Pause) {
|
||||||
var restart = makeRestartFunction(that);
|
var restart = makeRestartFunction(that, release);
|
||||||
e.onPause(restart);
|
e.onPause(restart);
|
||||||
release();
|
|
||||||
return;
|
return;
|
||||||
} else if (e instanceof HaltError) {
|
} else if (e instanceof HaltError) {
|
||||||
that.running = false;
|
that.running = false;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user