From 0ed9bdf5b8f9d824fec1cc46b3321ad4458c39b7 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Fri, 29 Jun 2012 16:04:24 +0200 Subject: [PATCH] Adopt dp's function-local backup strategy and add parameter-copying to EnterFunction --- exec.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/exec.c b/exec.c index e76eb4b..63d0e17 100644 --- a/exec.c +++ b/exec.c @@ -315,25 +315,49 @@ static void prog_print_statement(qc_program *prog, prog_section_statement *st) static qcint prog_enterfunction(qc_program *prog, prog_section_function *func) { qc_exec_stack st; - prog_section_function *cur = NULL; - - if (prog->stack_count) - cur = prog->stack[prog->stack_count-1].function; + size_t p, parampos; /* back up locals */ st.localsp = prog->localstack_count; st.stmt = prog->statement; st.function = func; - if (cur) +#ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS + if (prog->stack_count) { - qcint *globals = prog->globals + cur->firstlocal; - if (!qc_program_localstack_append(prog, globals, cur->locals)) + prog_section_function *cur; + cur = prog->stack[prog->stack_count-1].function; + if (cur) + { + qcint *globals = prog->globals + cur->firstlocal; + if (!qc_program_localstack_append(prog, globals, cur->locals)) + { + printf("out of memory\n"); + exit(1); + } + } + } +#else + { + qcint *globals = prog->globals + func->firstlocal; + if (!qc_program_localstack_append(prog, globals, func->locals)) { printf("out of memory\n"); exit(1); } } +#endif + + /* copy parameters */ + parampos = func->firstlocal; + for (p = 0; p < func->nargs; ++p) + { + size_t s; + for (s = 0; s < func->argsize[p]; ++s) { + prog->globals[parampos] = prog->globals[OFS_PARM0 + 3*p + s]; + ++parampos; + } + } if (!qc_program_stack_add(prog, st)) { printf("out of memory\n"); @@ -345,19 +369,34 @@ static qcint prog_enterfunction(qc_program *prog, prog_section_function *func) static qcint prog_leavefunction(qc_program *prog) { + prog_section_function *prev = NULL; + size_t oldsp; + qc_exec_stack st = prog->stack[prog->stack_count-1]; - if (!qc_program_stack_remove(prog, prog->stack_count-1)) { - printf("out of memory\n"); - exit(1); - } - if (st.localsp != prog->localstack_count) { - if (!qc_program_localstack_resize(prog, st.localsp)) { +#ifdef QCVM_BACKUP_STRATEGY_CALLER_VARS + if (prog->stack_count > 1) { + prev = prog->stack[prog->stack_count-2].function; + oldsp = prog->stack[prog->stack_count-2].localsp; + } +#else + prev = prog->stack[prog->stack_count-1].function; + oldsp = prog->stack[prog->stack_count-1].localsp; +#endif + if (prev) { + qcint *globals = prog->globals + prev->firstlocal; + memcpy(globals, prog->localstack + oldsp, prev->locals); + if (!qc_program_localstack_resize(prog, oldsp)) { printf("out of memory\n"); exit(1); } } + if (!qc_program_stack_remove(prog, prog->stack_count-1)) { + printf("out of memory\n"); + exit(1); + } + return st.stmt; } -- 2.39.2