diff options
-rw-r--r-- | ast.h | 6 | ||||
-rw-r--r-- | eval.c | 21 | ||||
-rw-r--r-- | tests/02_runtime/06_recursion | 35 |
3 files changed, 48 insertions, 14 deletions
@@ -74,7 +74,7 @@ struct ut_op { struct ut_scope { struct ut_scope *next; - struct json_object *scope, *ctx, *parent; + struct json_object *scope, *parent; size_t refs; }; @@ -88,7 +88,7 @@ struct ut_source { struct ut_function { char *name; struct json_object *args; - struct ut_scope *scope, *parent_scope; + struct ut_scope *parent_scope; struct ut_source *source; uint32_t entry; }; @@ -96,6 +96,8 @@ struct ut_function { struct ut_callstack { struct ut_callstack *next; struct ut_source *source; + struct ut_scope *scope; + struct json_object *ctx; char *funcname; uint32_t off; }; @@ -985,6 +985,7 @@ ut_invoke(struct ut_state *state, uint32_t off, struct json_object *this, callstack.source = state->source; callstack.funcname = state->function ? state->function->name : NULL; callstack.off = op ? op->off : 0; + callstack.ctx = json_object_get(this ? this : state->ctx); state->callstack = &callstack; /* is native function */ @@ -996,19 +997,19 @@ ut_invoke(struct ut_state *state, uint32_t off, struct json_object *this, /* is utpl function */ else { fn = tag->tag.data; - fn->scope = ut_new_scope(state, fn->parent_scope); - fn->scope->ctx = json_object_get(this ? this : state->ctx); + + callstack.scope = ut_new_scope(state, fn->parent_scope); sc = state->scope; - state->scope = ut_acquire_scope(fn->scope); + state->scope = ut_acquire_scope(callstack.scope); prev_fn = state->function; state->function = fn; if (fn->args) for (arridx = 0; arridx < json_object_array_length(fn->args); arridx++) - ut_setval(fn->scope->scope, json_object_array_get_idx(fn->args, arridx), + ut_setval(callstack.scope->scope, json_object_array_get_idx(fn->args, arridx), argvals ? json_object_array_get_idx(argvals, arridx) : NULL); rv = ut_execute_op_sequence(state, fn->entry); @@ -1033,17 +1034,13 @@ ut_invoke(struct ut_state *state, uint32_t off, struct json_object *this, ut_release_scope(state->scope); state->scope = sc; - /* ... and remove the "this" context... */ - json_object_put(fn->scope->ctx); - fn->scope->ctx = NULL; - - /* ... and reset the function scope... */ - ut_release_scope(fn->scope); - fn->scope = NULL; + /* ... and release it */ + ut_release_scope(callstack.scope); state->function = prev_fn; } + json_object_put(callstack.ctx); state->callstack = callstack.next; return rv; @@ -1369,7 +1366,7 @@ ut_execute_function(struct ut_state *state, uint32_t off) static struct json_object * ut_execute_this(struct ut_state *state, uint32_t off) { - return json_object_get(state->scope->ctx); + return json_object_get(state->callstack->ctx); } static struct json_object * diff --git a/tests/02_runtime/06_recursion b/tests/02_runtime/06_recursion new file mode 100644 index 0000000..e707c86 --- /dev/null +++ b/tests/02_runtime/06_recursion @@ -0,0 +1,35 @@ +Testing recursive invocations. + + +1. Testing recursive invocation. + +-- Expect stdout -- +1 +2 +4 +8 +16 +32 +64 +128 +256 +512 +1024 +2048 +4096 +8192 +16384 +-- End -- + +-- Testcase -- +{% + function test(x) { + print(x, "\n"); + + if (x < 10000) + test(x * 2); + } + + test(1); +%} +-- End -- |