+// So that we can detect when a finalizer illegally calls back into Haskell
+rtsBool running_finalizers = rtsFalse;
+
+void
+runCFinalizer(void *fn, void *ptr, void *env, StgWord flag)
+{
+ if (flag)
+ ((void (*)(void *, void *))fn)(env, ptr);
+ else
+ ((void (*)(void *))fn)(ptr);
+}
+
+void
+runAllCFinalizers(StgWeak *list)
+{
+ StgWeak *w;
+
+ running_finalizers = rtsTrue;
+
+ for (w = list; w; w = w->link) {
+ StgArrWords *farr;
+
+ farr = (StgArrWords *)UNTAG_CLOSURE(w->cfinalizer);
+
+ if ((StgClosure *)farr != &stg_NO_FINALIZER_closure)
+ runCFinalizer((void *)farr->payload[0],
+ (void *)farr->payload[1],
+ (void *)farr->payload[2],
+ farr->payload[3]);
+ }
+
+ running_finalizers = rtsFalse;
+}
+