avoiding the internal error by explicitly checking the arity

This commit is contained in:
Danny Yoo 2012-03-15 16:28:16 -04:00
parent 441c40d305
commit 5798e28801
4 changed files with 46 additions and 17 deletions

View File

@ -134,14 +134,19 @@
}; };
var raiseArityMismatchError = function(MACHINE, proc, received) { var raiseArityMismatchError = function(MACHINE, proc, received) {
raise(MACHINE, makeArityMismatchError(MACHINE, proc, received));
};
var makeArityMismatchError = function(MACHINE, proc, received) {
var message = baselib.format.format("~a: expected ~e value(s), received ~e value(s)", var message = baselib.format.format("~a: expected ~e value(s), received ~e value(s)",
[proc.displayName, [proc.displayName,
proc.racketArity, proc.racketArity,
received]); received]);
var contMarks = MACHINE.captureContinuationMarks(); var contMarks = MACHINE.captureContinuationMarks();
raise(MACHINE, ExnFailContractArity.constructor([message, contMarks])); return ExnFailContractArity.constructor([message, contMarks]);
}; };
var raiseOperatorApplicationError = function(MACHINE, operator) { var raiseOperatorApplicationError = function(MACHINE, operator) {
var message = baselib.format.format("not a procedure: ~e", var message = baselib.format.format("not a procedure: ~e",
[operator]); [operator]);
@ -233,6 +238,7 @@
exceptions.raiseArgumentTypeError = raiseArgumentTypeError; exceptions.raiseArgumentTypeError = raiseArgumentTypeError;
exceptions.raiseContextExpectedValuesError = raiseContextExpectedValuesError; exceptions.raiseContextExpectedValuesError = raiseContextExpectedValuesError;
exceptions.raiseArityMismatchError = raiseArityMismatchError; exceptions.raiseArityMismatchError = raiseArityMismatchError;
exceptions.makeArityMismatchError = makeArityMismatchError;
exceptions.raiseOperatorApplicationError = raiseOperatorApplicationError; exceptions.raiseOperatorApplicationError = raiseOperatorApplicationError;
exceptions.raiseOperatorIsNotPrimitiveProcedure = raiseOperatorIsNotPrimitiveProcedure; exceptions.raiseOperatorIsNotPrimitiveProcedure = raiseOperatorIsNotPrimitiveProcedure;
exceptions.raiseUnimplementedPrimitiveError = raiseUnimplementedPrimitiveError; exceptions.raiseUnimplementedPrimitiveError = raiseUnimplementedPrimitiveError;

View File

@ -171,6 +171,7 @@
// with two computations, with use of setTimeout. // with two computations, with use of setTimeout.
var ExclusiveLock = function() { var ExclusiveLock = function() {
this.locked = false; // (U false string) this.locked = false; // (U false string)
this.alreadyReleased = false;
this.waiters = []; this.waiters = [];
}; };
@ -193,16 +194,17 @@
id = ExclusiveLock.makeRandomNonce(); id = ExclusiveLock.makeRandomNonce();
} }
var alreadyReleased = false; this.alreadyReleased = false;
if (this.locked === false) { if (this.locked === false) {
console.log("lock is clear. Grabbing...");
this.locked = id; this.locked = id;
onAcquire.call( onAcquire.call(
that, that,
// releaseLock // releaseLock
function() { function() {
var waiter; var waiter;
if (alreadyReleased) { if (that.alreadyReleased) {
throw new Error( throw new Error(
"Internal error: trying to release the lock, but already released"); "Internal error: trying to release the lock, but already released");
} }
@ -211,17 +213,19 @@
"Internal error: trying to unlock the lock, but already unlocked"); "Internal error: trying to unlock the lock, but already unlocked");
} }
that.locked = false; that.locked = false;
alreadyReleased = true; that.alreadyReleased = true;
if (that.waiters.length > 0) { if (that.waiters.length > 0) {
waiter = that.waiters.shift(); waiter = that.waiters.shift();
setTimeout( setTimeout(
function() { function() {
console.log("trying to re-acquire lock...");
that.acquire(waiter.id, waiter.onAcquire); that.acquire(waiter.id, waiter.onAcquire);
}, },
0); 0);
} }
}); });
} else { } else {
console.log("lock is currently in play. Need to wait.");
this.waiters.push({ id: id, this.waiters.push({ id: id,
onAcquire: onAcquire } ); onAcquire: onAcquire } );
} }
@ -580,6 +584,7 @@
}); });
}; };
var internalCall = function(proc, success, fail) { var internalCall = function(proc, success, fail) {
console.log("internalCall");
var i; var i;
if (restarted) { if (restarted) {
return; return;
@ -588,15 +593,20 @@
for (i = 3; i < arguments.length; i++) { for (i = 3; i < arguments.length; i++) {
args.push(arguments[i]); args.push(arguments[i]);
} }
console.log("acquiring lock...");
pauseLock.acquire( pauseLock.acquire(
void(0), void(0),
function(release) { function(release) {
var newSuccess = function() { var newSuccess = function() {
console.log('newSuccess', arguments, proc, success);
success.apply(null, arguments); success.apply(null, arguments);
console.log("releasing lock...");
release(); release();
}; };
var newFail = function() { var newFail = function() {
console.log('newFail', arguments, proc, fail);
fail.apply(null, arguments); fail.apply(null, arguments);
console.log("releasing lock...");
release(); release();
}; };
baselib.functions.internalCallDuringPause.apply( baselib.functions.internalCallDuringPause.apply(
@ -614,7 +624,9 @@
// General error condition: just exit out // General error condition: just exit out
// of the trampoline and call the current error handler. // of the trampoline and call the current error handler.
that.running = false; that.running = false;
console.log("calling current error handler", that.params.currentErrorHandler);
that.params.currentErrorHandler(that, e); that.params.currentErrorHandler(that, e);
console.log("releasing");
release(); release();
return; return;
} }

View File

@ -5,5 +5,5 @@
(big-bang (list 'undefined 'undefined) (big-bang (list 'undefined 'undefined)
(on-geo (lambda (w v lat lng) (on-geo (lambda (w v lat #;lng)
(list lat lng)))) (list lat #;lng))))

View File

@ -17,6 +17,7 @@
var makePair = plt.baselib.lists.makePair; var makePair = plt.baselib.lists.makePair;
var makeSymbol = plt.baselib.symbols.makeSymbol; var makeSymbol = plt.baselib.symbols.makeSymbol;
var isArityMatching = plt.baselib.arity.isArityMatching; var isArityMatching = plt.baselib.arity.isArityMatching;
var makeArityMismatchError = plt.baselib.exceptions.makeArityMismatchError;
// EventHandler and the other classes here will be defined below. // EventHandler and the other classes here will be defined below.
@ -1197,6 +1198,7 @@
dispatchEventsInQueue, refreshView; dispatchEventsInQueue, refreshView;
onCleanRestart = function() { onCleanRestart = function() {
console.log('on clean restart');
running = false; running = false;
stopEventHandlers( stopEventHandlers(
function() { function() {
@ -1209,12 +1211,16 @@
}; };
onMessyRestart = function(exn) { onMessyRestart = function(exn) {
console.log('on messy restart');
running = false; running = false;
console.log('stopping the event handlers');
stopEventHandlers( stopEventHandlers(
function() { function() {
console.log('event handlers stopped');
restart(function(MACHINE) { restart(function(MACHINE) {
currentBigBangRecord = oldCurrentBigBangRecord; currentBigBangRecord = oldCurrentBigBangRecord;
MACHINE.params.currentOutputPort = oldOutputPort; MACHINE.params.currentOutputPort = oldOutputPort;
console.log('about to raise');
plt.baselib.exceptions.raise(MACHINE, exn); plt.baselib.exceptions.raise(MACHINE, exn);
}); });
}); });
@ -1235,15 +1241,11 @@
eventQueue.queue(new EventQueueElement(who, handler, args)); eventQueue.queue(new EventQueueElement(who, handler, args));
if (! dispatchingEvents) { if (! dispatchingEvents) {
dispatchingEvents = true; dispatchingEvents = true;
setTimeout( dispatchEventsInQueue(
function() { function() {
dispatchEventsInQueue( refreshView(function() {}, onMessyRestart);
function() { },
refreshView(function() {}, onMessyRestart); onMessyRestart);
},
onMessyRestart);
},
0);
} }
}; };
handler.eventSource.onStart(fireEvent, internalCall, k); handler.eventSource.onStart(fireEvent, internalCall, k);
@ -1255,6 +1257,7 @@
dispatchEventsInQueue = function(success, fail) { dispatchEventsInQueue = function(success, fail) {
console.log("dispatchEventsInQueue");
// Apply all the events on the queue, call toDraw, and then stop. // Apply all the events on the queue, call toDraw, and then stop.
// If the world ever satisfies stopWhen, stop immediately and quit. // If the world ever satisfies stopWhen, stop immediately and quit.
var nextEvent; var nextEvent;
@ -1274,7 +1277,8 @@
racketWorldCallback = nextEvent.handler.racketWorldCallback; racketWorldCallback = nextEvent.handler.racketWorldCallback;
args = nextEvent.data.slice(0); args = nextEvent.data.slice(0);
var onGoodWorldUpdate = var onGoodWorldUpdate =
function(newWorld) { function (newWorld) {
console.log("good world update");
world = newWorld; world = newWorld;
stopWhen(internalCall, stopWhen(internalCall,
world, world,
@ -1290,23 +1294,29 @@
fail); fail);
}; };
if (isArityMatching(racketWorldCallback.racketArity, 1)) { if (isArityMatching(racketWorldCallback.racketArity, 1)) {
console.log("arity match 1");
racketWorldCallback(internalCall, racketWorldCallback(internalCall,
world, world,
onGoodWorldUpdate, onGoodWorldUpdate,
fail); fail);
} else if (isArityMatching(racketWorldCallback.racketArity, 2)) { } else if (isArityMatching(racketWorldCallback.racketArity, 2)) {
console.log("arity match 2");
racketWorldCallback(internalCall, racketWorldCallback(internalCall,
world, world,
mockView, mockView,
onGoodWorldUpdate, onGoodWorldUpdate,
fail); fail);
} else { } else if (isArityMatching(racketWorldCallback.racketArity, 2 + args.length)){
console.log("arity match 3");
args = ([internalCall, world, mockView] args = ([internalCall, world, mockView]
.concat(args) .concat(args)
.concat([onGoodWorldUpdate, fail])); .concat([onGoodWorldUpdate, fail]));
racketWorldCallback.apply(null, args); racketWorldCallback.apply(null, args);
} else {
fail(makeArityMismatchError(MACHINE, racketWorldCallback, 2+args.length));
} }
} else { } else {
console.log("dispatched all events");
dispatchingEvents = false; dispatchingEvents = false;
success(); success();
} }
@ -1369,6 +1379,7 @@
success, success,
fail].concat(args)); fail].concat(args));
}; };
f.displayName = proc.displayName;
f.racketArity = proc.racketArity; f.racketArity = proc.racketArity;
return f; return f;
}; };