shithub: MicroHs

Download patch

ref: 725a051580be423d4b35f7afa0a99c03a99a73dc
parent: ae92dd514636a93bbbf9c7b59aa6939e46856dea
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Mon Nov 20 11:55:40 EST 2023

Make safer.

--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -1670,17 +1670,21 @@
   }
 }
 
+bits_t *rnf_bits;
+
 void
 rnf_rec(NODEPTR n)
 {
  top:
-  if (test_bit(marked_bits, n))
+  if (test_bit(rnf_bits, n))
     return;
-  set_bit(marked_bits, n);
+  set_bit(rnf_bits, n);
   n = evali(n);
   if (GETTAG(n) == T_AP) {
+    PUSH(ARG(n));               /* protect from GC */
     rnf_rec(FUN(n));
-    n = ARG(n);
+    n = TOP(0);
+    POP(1);
     goto top;
   }
 }
@@ -1692,8 +1696,8 @@
 rnf(value_t noerr, NODEPTR n)
 {
   /* Mark visited nodes to avoid getting stuck in loops. */
-  marked_bits = calloc(free_map_nwords, sizeof(bits_t));
-  if (!marked_bits)
+  rnf_bits = calloc(free_map_nwords, sizeof(bits_t));
+  if (!rnf_bits)
     memerr();
   if (doing_rnf)
     ERR("recursive rnf()");
@@ -1700,7 +1704,7 @@
   doing_rnf = (int)noerr;
   rnf_rec(n);
   doing_rnf = 0;
-  free(marked_bits);
+  free(rnf_bits);
 }
 
 NODEPTR evalio(NODEPTR n);
--