Add GC segments to differentiate C stack space from Lisp
diff --git a/src/lisp/gc.h b/src/lisp/gc.h
index 789e124..77e382a 100644
--- a/src/lisp/gc.h
+++ b/src/lisp/gc.h
@@ -4,6 +4,47 @@
 
 // I hate this
 extern value_t *gc_base;
+extern struct gc_segment *gc_last_segment;
+
+struct gc_segment
+{
+	struct gc_segment *prev;
+
+	// The address of the first dword on the stack below the return
+	// pointer for this function (i.e. when the procedure is first
+	// `call`'d, this is esp+4)
+	void *seg_start;
+
+	// The address of the return pointer for the subsequently called
+	// function on the stack. When the lisp function is called,
+	// seg_end=esp.
+	void *seg_end;
+
+	// The number of arguments passed to the lisp function. These are
+	// stored in order on the stack, starting at seg_end+4, each
+	// taking 1 dword of memory.
+	int nargs;
+
+	// The value of ebp as it was when the function was first
+	// invoked. This denotes the caller's stack frame.
+	void *old_ebp;
+
+	// The number of lisp values which are retained by this C
+	// function.
+	int nretained;
+	value_t retained[];
+};
+
+#define gc_prepare_call(nargs)								   \
+	{														   \
+		void *__gc_segment_base;							   \
+		asm("movl %%esp, %0" : "=g"(__gc_segment_base));	   \
+		gc_prepare_call_(__gc_segment_base,	nargs);			   \
+	}
+void gc_push_segment(void *last_arg_addr, int nretained);
+void gc_pop_segment();
+void gc_prepare_call_(void *esp, int nargs);
+void gc_set_retained(int index, value_t retained);
 
 struct gc_stats
 {