From: David Kerkeslager Date: Mon, 25 Sep 2017 21:49:12 +0000 (-0400) Subject: Clean up stacks in the case of an exception X-Git-Url: https://code.kerkeslager.com/?p=fur;a=commitdiff_plain;h=4c47216656579a0e5b81cc3fbab17362ffde3e94;hp=85dd9abe3cd977cd7f9bdeb9aea15c5b4135d0b2 Clean up stacks in the case of an exception --- diff --git a/templates/function_definition.c b/templates/function_definition.c index 72ce6f0..9ebac36 100644 --- a/templates/function_definition.c +++ b/templates/function_definition.c @@ -1,21 +1,32 @@ -Object user${{name}}$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Stack* stack, jmp_buf parent_jump) +Object user${{name}}$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Stack* parentStack, jmp_buf parent_jump) { Environment* environment = EnvironmentPool_allocate(environmentPool); Environment_initialize(environment, parent); + Stack stackMemory; + Stack* stack = &stackMemory; + Stack_initialize(stack); + jmp_buf jump; if(setjmp(jump) != 0) { - Environment_setLive(environment, false); fprintf(stderr, "\tin {{name}}\n"); + + while(Stack_any(stack)) + { + Object item = Stack_pop(stack); + Object_deinitialize(&item); + } + Environment_setLive(environment, false); + longjmp(parent_jump, 1); } Object result = builtin$nil; {% for argument_name in argument_name_list|reverse %} - Environment_set(environment, "{{ argument_name }}", Stack_pop(stack)); + Environment_set(environment, "{{ argument_name }}", Stack_pop(parentStack)); {% endfor %} {% for statement in statement_list %} diff --git a/templates/program.c b/templates/program.c index 08921b1..7cfd1e3 100644 --- a/templates/program.c +++ b/templates/program.c @@ -163,6 +163,11 @@ void Stack_initialize(Stack* self) self->length = 0; } +bool Stack_any(Stack* self) +{ + return self->length > 0; +} + void Stack_push(Stack* self, Object item) { assert(self->length < 256); @@ -695,6 +700,12 @@ int main(int argc, char** argv) if(setjmp(jump) != 0) { fprintf(stderr, "\tin __main__\n"); + + while(Stack_any(stack)) + { + Object item = Stack_pop(stack); + Object_deinitialize(&item); + } Environment_setLive(environment, false); EnvironmentPool_destruct(environmentPool);