[gamecode] Move return buffer to end of progs memory map

With the return buffer in progs_t, it could not be addressed by the
progs on 64-bit machines (this was intentional, actually), but in order
to get obj_msg_sendv working properly, I needed a way to "bounce" the
return address of a calling function to the called function. The
cleanest solution I could think of was to add a mode to the with
instruction allowing the return pointer to be loaded into a register and
then calling the function with a 0 offset for the return value but using
the relevant register (next few commits). Testing promptly segfaulted
due to the 64-bit offset not fitting into a 32-bit value.
This commit is contained in:
Bill Currie 2022-02-05 18:37:23 +09:00
parent b0810958e7
commit 208cba85eb
3 changed files with 6 additions and 2 deletions

View file

@ -1960,7 +1960,7 @@ struct progs_s {
pr_type_t *pr_real_params[PR_MAX_PARAMS];
int pr_param_size; ///< covers both params and return
int pr_param_alignment; ///< covers both params and return
pr_type_t pr_return_buffer[32];///< for discarded return values
pr_type_t *pr_return_buffer; ///< for discarded return values
///< or returning values to C
///@}

View file

@ -522,6 +522,7 @@ typedef struct dparmsize_s {
#define DEF_SAVEGLOBAL (1<<15)
#define PR_MAX_PARAMS 8
#define PR_MAX_RETURN 32 // maximum size of return value
typedef struct dfunction_s {
pr_int_t first_statement; // negative numbers are builtins

View file

@ -199,6 +199,8 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
mem_size = pr->pr_edict_area_size * sizeof (pr_type_t);
mem_size += pr->progs_size + pr->zone_size + pr->stack_size;
// space for return buffer
mem_size += PR_MAX_RETURN * sizeof (pr_type_t);
// +1 for a nul terminator
pr->progs = pr->allocate_progs_mem (pr, mem_size + 1);
@ -240,6 +242,7 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
if (pr->globals.stack && pr->stack_bottom) {
*pr->globals.stack = pr->globals_size;
}
pr->pr_return_buffer = pr->pr_globals + pr->globals_size;
if (pr->zone) {
PR_Zone_Init (pr);