altos/lisp: Simplify GC a bit by only marking the head of each object
[fw/altos] / src / lisp / ao_lisp_eval.c
index ae2436b8cd86d7026bde5b1bc7347abaced9ba00..04d0e70a2f79eeeee957ee01df3ced52575478db 100644 (file)
@@ -16,6 +16,8 @@
 #include "ao_lisp.h"
 #include <assert.h>
 
+const struct ao_lisp_type ao_lisp_stack_type;
+
 static int
 stack_size(void *addr)
 {
@@ -32,14 +34,13 @@ stack_mark(void *addr)
                ao_lisp_poly_mark(stack->values, 0);
                /* no need to mark values_tail */
                ao_lisp_poly_mark(stack->frame, 0);
+               ao_lisp_poly_mark(stack->list, 0);
                stack = ao_lisp_poly_stack(stack->prev);
-               if (ao_lisp_mark_memory(stack, sizeof (struct ao_lisp_stack)))
+               if (ao_lisp_mark_memory(&ao_lisp_stack_type, stack))
                        break;
        }
 }
 
-static const struct ao_lisp_type ao_lisp_stack_type;
-
 static void
 stack_move(void *addr)
 {
@@ -47,14 +48,16 @@ stack_move(void *addr)
 
        while (stack) {
                struct ao_lisp_stack    *prev;
-               int     ret;
+               int                     ret;
                (void) ao_lisp_poly_move(&stack->sexprs, 0);
                (void) ao_lisp_poly_move(&stack->values, 0);
                (void) ao_lisp_poly_move(&stack->values_tail, 0);
                (void) ao_lisp_poly_move(&stack->frame, 0);
+               (void) ao_lisp_poly_move(&stack->list, 0);
                prev = ao_lisp_poly_stack(stack->prev);
-               ret = ao_lisp_move_memory((void **) &prev,
-                                         sizeof (struct ao_lisp_stack));
+               if (!prev)
+                       break;
+               ret = ao_lisp_move_memory(&ao_lisp_stack_type, (void **) &prev);
                if (prev != ao_lisp_poly_stack(stack->prev))
                        stack->prev = ao_lisp_stack_poly(prev);
                if (ret)
@@ -63,10 +66,11 @@ stack_move(void *addr)
        }
 }
 
-static const struct ao_lisp_type ao_lisp_stack_type = {
+const struct ao_lisp_type ao_lisp_stack_type = {
        .size = stack_size,
        .mark = stack_mark,
-       .move = stack_move
+       .move = stack_move,
+       .name = "stack"
 };
 
 struct ao_lisp_stack           *ao_lisp_stack;
@@ -542,17 +546,28 @@ static int (*const evals[])(void) = {
        [eval_while_test] = ao_lisp_eval_while_test,
 };
 
+/*
+ * Called at restore time to reset all execution state
+ */
+
+void
+ao_lisp_eval_clear_globals(void)
+{
+       ao_lisp_stack = NULL;
+       ao_lisp_frame_current = NULL;
+       ao_lisp_v = AO_LISP_NIL;
+}
+
+int
+ao_lisp_eval_restart(void)
+{
+       return ao_lisp_stack_push();
+}
+
 ao_poly
 ao_lisp_eval(ao_poly _v)
 {
-       static uint8_t been_here;
-
        ao_lisp_v = _v;
-       if (!been_here) {
-               been_here = 1;
-               ao_lisp_root_add(&ao_lisp_stack_type, &ao_lisp_stack);
-               ao_lisp_root_poly_add(&ao_lisp_v);
-       }
 
        if (!ao_lisp_stack_push())
                return AO_LISP_NIL;