Fix a bug where finalizers would run before they were supposed to.
I reproduced this bug by using my Freecell example at
http://github.com/the-real-blackh/sodium-2d-game-engine/
I also hacked the generated Javascript in the following ways to
make the bug happen more often:
1. Modify the main loop so it looks like this:
     // preemptively schedule threads after 9990 calls
     // but not earlier than after 25ms
     try {
          c = c();
          c = c();
          c = c();
          c = c();
     } catch(e) {
       // uncaught exception in haskell code, kill thread
       // would we ever need to remove the thread from queues?
   (This makes it so it only runs 4 instructions before trying a gc).
2. Modify scheduler so it runs gc each time it continues on the same
   thread:
@@ -400,7 +400,6 @@ function h$scheduler(next) {
     h$logSched("sched: no other runnable threads");
     if(h$currentThread && h$currentThread.status === h$threadRunning) {
       // do gc after a while
-      if(now - h$lastGc > h$gcInterval) {
         if(next !== h$reschedule && next !== null) {
           h$suspendCurrentThread(next);
           next = h$stack[h$sp];
@@ -408,7 +407,6 @@ function h$scheduler(next) {
         h$gc(h$currentThread);
         h$stack = h$currentThread.stack;
         h$lastGc = Date.now();
-      }
 //      if(h$postAsync(next === h$reschedule, next)) {
 //        h$logSched("sched: continuing: " + h$threadString(h$currentThread) + " (async posted)"); // fixme we can remove these, we handle async
 //        return h$stack[h$sp];  // async exception posted, jump to the new stack top
3. Modify finalizeWeaks so it tells us when it's doing its thing:
@@ -26,6 +27,9 @@ function h$finalizeWeaks() {
   traceWeak("to finalize: " + toFinalize.length + " checked: " + checked);
   // start a finalizer thread if any finalizers need to be run
   if(toFinalize.length > 0) {
+    console.log("to finalize: " + toFinalize.length + " checked: " + checked);
+    if (toFinalize.length > 100)
+        console.log("BANG!");
     var t = new h$Thread();
     for(var i=0;i<toFinalize.length;i++) {
       var w = toFinalize[i];
If it says BANG! then it has failed.