Fix memory leaks in compiler
diff --git a/src/lisp/Jmk2 b/src/lisp/Jmk2
index 5446f50..b9398ac 100644
--- a/src/lisp/Jmk2
+++ b/src/lisp/Jmk2
@@ -34,6 +34,11 @@
 	shell "LISP_LIBRARY_PATH=$::lisp_libpath ./lisp $::root/lib/lisp/repl/repl.lisp"
 }
 
+rule valgrind [pwd]/lisp {
+	log VALGRIND "lisp test-gc.lisp"
+	shell "LISP_LIBRARY_PATH=$::lisp_libpath valgrind --track-origins=yes --leak-check=full ./lisp test-gc.lisp"
+}
+
 srcs main.c lisp.c compiler.c lib/std.c plat/linux.c istream.c gc.c \
 	call_list.s error.c
 
diff --git a/src/lisp/compiler.dasc b/src/lisp/compiler.dasc
index a0b0236..122538c 100644
--- a/src/lisp/compiler.dasc
+++ b/src/lisp/compiler.dasc
@@ -105,6 +105,8 @@
 	{
 		next = f->prev;
 		// We're not gonna bother munmap()ing the function
+		if (f->args)
+			free(f->args);
 		free(f);
 	}
 
@@ -207,10 +209,15 @@
 
 	if (local_out)
 		*local_out = local;
+	else
+		del_local(&local);
 
 	if (args_out)
 		*args_out = ar;
 
+	if (!local_out && !args_out)
+		free(ar);
+
 	*state = d;
 
 	OKAY();
@@ -408,6 +415,8 @@
 
 	snprintf(full_path, 512, "%s/%s", dirname(relative_to), new_path);
 
+	free(relative_to);
+
 	if (load(env, full_path))
 		return t;
 	else
@@ -775,7 +784,7 @@
 		{
 			// Compile the function with this as the parent scope
 			struct local new_local;
-			int nargs_out;
+			struct args *nargs_out;
 			dasm_State *d;
 			TRY(compile_function(
 					args, NS_ANONYMOUS, env, &new_local, local, &nargs_out,
@@ -1251,6 +1260,8 @@
 
 			add_variable(local, V_ARGUMENT, (char *)(name ^ SYMBOL_TAG),
 			             args->num_required + args->num_optional - 1);
+
+			dasm_free(&d);
 		}
 	}
 
diff --git a/src/lisp/compiler.h b/src/lisp/compiler.h
index 340d955..62f1b69 100644
--- a/src/lisp/compiler.h
+++ b/src/lisp/compiler.h
@@ -152,8 +152,11 @@
 void local_free(struct local *local, unsigned int slot);
 
 /**
- * Deletes the memory allocated in `local`. Does not actually call `free()` on
- * `local` itself, but frees the variables and stack slots associated with it.
+ * Deletes the memory allocated in `local`. Does not actually call
+ * `free()` on `local` itself, but frees the variables and stack slots
+ * associated with it.  Also does NOT free `local->args`. You must do
+ * that yourself if you want. This is because these arguments are
+ * often used in multiple places.
  */
 void del_local(struct local *local);
 
diff --git a/src/lisp/gc.c b/src/lisp/gc.c
index 06d8a07..140bc3f 100644
--- a/src/lisp/gc.c
+++ b/src/lisp/gc.c
@@ -84,14 +84,23 @@
 		}
 		else
 		{
-			fprintf(stderr, "[ GC ] freeing: ");
-			printval(alloc_to_value(a), 1);
+			fprintf(stderr, "[ GC ] freeing: %p\n", a);
 			// Free and remove from allocation list
 			struct alloc *p = a->prev, *n = a->next;
-			free_aligned(a);
+			del_alloc(a);
 
 			a = n;
 
+			if (a == first_a)
+			{
+				first_a = n;
+			}
+
+			if (a == last_a)
+			{
+				last_a = p;
+			}
+
 			if (p)
 				p->next = n;
 
@@ -152,7 +161,7 @@
 	for (struct alloc *a = first_a; a;)
 	{
 		struct alloc *next = a->next;
-		free_aligned(a);
+		del_alloc(a);
 		a = next;
 //		fprintf(stderr, "a = %p\n", a);
 	}
diff --git a/src/lisp/lisp.c b/src/lisp/lisp.c
index ac6470d..6299e03 100644
--- a/src/lisp/lisp.c
+++ b/src/lisp/lisp.c
@@ -25,6 +25,7 @@
 
 void add_this_alloc(struct alloc *a, int tag)
 {
+	a->mark = -1;
 	a->type_tag = tag;
 	a->pool = current_pool;
 
@@ -600,6 +601,18 @@
 	a[-1].pool = current_pool;
 }
 
+void del_alloc(struct alloc *alloc)
+{
+	if (alloc->type_tag == CLOSURE_TAG)
+	{
+		fprintf(stderr, "del_alloc closure\n");
+		struct closure_alloc *ca = alloc;
+		free(ca->closure.args);
+	}
+
+	free_aligned(alloc);
+}
+
 int cons_line(value_t val)
 {
 	if (!consp(val))
diff --git a/src/lisp/lisp.h b/src/lisp/lisp.h
index e41ebff..ad7314a 100644
--- a/src/lisp/lisp.h
+++ b/src/lisp/lisp.h
@@ -149,6 +149,8 @@
 
 void add_to_pool(value_t form);
 
+void del_alloc(struct alloc *alloc);
+
 /**
  * @returns true if pool is still alive (in scope).
  */
diff --git a/src/lisp/main.c b/src/lisp/main.c
index f78b3b1..a9231b8 100644
--- a/src/lisp/main.c
+++ b/src/lisp/main.c
@@ -1,6 +1,6 @@
 #include "compiler.h"
-#include "lisp.h"
 #include "gc.h"
+#include "lisp.h"
 #include "plat/plat.h"
 
 int main(int argc, char **argv)
@@ -18,7 +18,7 @@
 	{
 		ereport(compile_error);
 		goto done;
-	}		
+	}
 
 	struct function *lisp_main_f = find_function(env, "main");