From 247114748823f02a1c497c8332fe8ca401a84d80 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 7 Mar 2024 22:12:24 +0900 Subject: [PATCH] [gamecode] Save return pointer when saving params And point the return pointer at the return buffer. And, of course, restore it. This fixes a really subtle (ie, difficult to find) bug caused by the recent optimization improvements in qfcc: the optimizer had decided to set the return value of a message call to the parameter for the next call, but because the message was to the receiver class for the first time, the class's +initialize was called. The +initialize method returned self, which of course when into the parameter for the *next* call, but the first call hadn't been made, so its parameter got corrupted. --- include/QF/progs.h | 1 + libs/gamecode/pr_exec.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/QF/progs.h b/include/QF/progs.h index 654120cac..95210cb62 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -117,6 +117,7 @@ void PR_RunError (progs_t *pr, const char *error, ...) __attribute__((format(PRI ///@{ typedef struct pr_stashed_params_s { pr_type_t *param_ptrs[2]; + pr_type_t *return_ptr; int argc; pr_type_t params[1]; } pr_stashed_params_t; diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index 056998add..762c3b5ba 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -104,8 +104,10 @@ _PR_SaveParams (progs_t *pr, pr_stashed_params_t *params) params->param_ptrs[0] = pr->pr_params[0]; params->param_ptrs[1] = pr->pr_params[1]; + params->return_ptr = pr->pr_return; pr->pr_params[0] = pr->pr_real_params[0]; pr->pr_params[1] = pr->pr_real_params[1]; + pr->pr_return = pr->pr_return_buffer; for (i = 0; i < pr->pr_argc; i++) { memcpy (params->params + i * pr->pr_param_size, pr->pr_real_params[i], size); @@ -122,6 +124,7 @@ PR_RestoreParams (progs_t *pr, pr_stashed_params_t *params) pr->pr_params[0] = params->param_ptrs[0]; pr->pr_params[1] = params->param_ptrs[1]; + pr->pr_return = params->return_ptr; pr->pr_argc = params->argc; for (i = 0; i < pr->pr_argc; i++) { memcpy (pr->pr_real_params[i],