From 213434b7054d3f4991a52ea0b4346a7c15d94aec Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 17 Jan 2022 14:45:14 +0900 Subject: [PATCH] [gamecode] Save and restore data stack in call stack This fixes the issue of the data stack not being restored properly because the returning function needs to return a value from its local variables (stored on the stack) and accessing stack data below the stack pointer is a bad idea (sure, no interrupts yet, but who knows...). --- include/QF/progs.h | 1 + libs/gamecode/pr_exec.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/QF/progs.h b/include/QF/progs.h index 55ac37b69..1597c97df 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -1802,6 +1802,7 @@ typedef struct strref_s strref_t; typedef struct { pr_uint_t staddr; ///< Return statement. + pr_uint_t stack_ptr; ///< data stack on entry to function bfunction_t *func; ///< Calling function. strref_t *tstr; ///< Linked list of temporary strings. } prstack_t; diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index d2f55dbd7..cf01b0e8a 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -143,6 +143,9 @@ PR_PushFrame (progs_t *pr) frame = pr->pr_stack + pr->pr_depth++; frame->staddr = pr->pr_xstatement; + if (pr->globals.stack) { + frame->stack_ptr = *pr->globals.stack; + } frame->func = pr->pr_xfunction; frame->tstr = pr->pr_xtstr; @@ -179,6 +182,10 @@ PR_PopFrame (progs_t *pr) pr->pr_xfunction = frame->func; pr->pr_xstatement = frame->staddr; pr->pr_xtstr = frame->tstr; + // restore data stack (discard any locals) + if (pr->globals.stack) { + *pr->globals.stack = frame->stack_ptr; + } } static __attribute__((pure)) long