summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2014-02-02 17:38:04 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2014-02-02 17:38:04 -0500
commitbe0983a56afc1bedf9e5cdc12e2891789891bba1 (patch)
treee45a45b5c0222ebaeed37925bcd4cb2b38cb6554
parent209f22b69cfa5b04c00f75aceaecfdb313a880bb (diff)
Save and restore the stack across calls
-rw-r--r--interpret.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/interpret.c b/interpret.c
index 7815e80..371d372 100644
--- a/interpret.c
+++ b/interpret.c
@@ -265,11 +265,6 @@ interpret (ast_t *ast)
case NODE_DYN_CLOSURE:
stack = stack_pop (stack, &val);
-
-#if 0
- g_print ("obj: %p\n", val.pointer_val);
-#endif
-
val.closure_val.env = val.pointer_val;
val.closure_val.function = current->dyn_closure.function;
stack = stack_push (stack, val);
@@ -325,13 +320,13 @@ interpret (ast_t *ast)
old_env = env;
old_next = next;
- /* Make new environment */
stack = stack_pop (stack, &val);
closure = &val.closure_val;
if (!closure->function)
g_error ("Attempting to run a NULL closure\n");
+ /* Make new environment */
env = gc_alloc (closure->function->env_size);
*((gpointer *)env + 0) = closure->env; /* outer */
*((gpointer *)env + 1) = old_env;
@@ -345,14 +340,18 @@ interpret (ast_t *ast)
/* Copy parameters to environment */
for (i = 0; closure->function->parameters[i]; ++i)
{
- ast_variable_definition_t *parameter = closure->function->parameters[i];
+ ast_variable_definition_t *parameter;
value_t value;
+ parameter = closure->function->parameters[i];
stack = stack_pop (stack, &value);
- write_value (env + parameter->offset, parameter->type_spec, &value);
+ write_value (
+ env + parameter->offset, parameter->type_spec, &value);
}
+ *((gpointer *)env + 3) = stack;
+ stack = NULL;
next = closure->function->enter;
break;
@@ -368,13 +367,21 @@ interpret (ast_t *ast)
case NODE_NEW_ARRAY:
stack = stack_pop (stack, &val);
- val.pointer_val = gc_alloc (val.int32_val * current->new_array.element_size);
+ val.pointer_val = gc_alloc (
+ val.int32_val * current->new_array.element_size);
stack = stack_push (stack, val);
break;
case NODE_RETURN:
+ stack = stack_pop (stack, &val);
+
+ g_assert (stack == NULL);
+
next = *((gpointer *)env + 2);
+ stack = *((gpointer *)env + 3);
env = *((gpointer *)env + 1);
+
+ stack = stack_push (stack, val);
break;
case NODE_THIS: