diff --git a/include/QF/progs.h b/include/QF/progs.h index d2a923743..634eb38a0 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -175,10 +175,12 @@ void PR_ExecuteProgram (progs_t *pr, func_t fnum); execute upon return of control to PR_ExecuteProgram(). \param pr pointer to ::progs_t VM struct \param fnum number of the function to call + \param return_ptr pointer to location in which return values will be + written \return true if \p fnum was a progs function, false if \p fnum was a builtin */ -int PR_CallFunction (progs_t *pr, func_t fnum); +int PR_CallFunction (progs_t *pr, func_t fnum, pr_type_t *return_ptr); ///@} @@ -1806,6 +1808,7 @@ typedef struct { pr_uint_t stack_ptr; ///< data stack on entry to function bfunction_t *func; ///< Calling function. strref_t *tstr; ///< Linked list of temporary strings. + pr_type_t *return_ptr; ///< Saved return address } prstack_t; struct progs_s { diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index 90296c153..a8585fc2b 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -149,6 +149,7 @@ PR_PushFrame (progs_t *pr) frame->bases = pr->pr_bases; frame->func = pr->pr_xfunction; frame->tstr = pr->pr_xtstr; + frame->return_ptr = pr->pr_return; pr->pr_xtstr = pr->pr_pushtstr; pr->pr_pushtstr = 0; @@ -180,6 +181,7 @@ PR_PopFrame (progs_t *pr) // up stack frame = pr->pr_stack + --pr->pr_depth; + pr->pr_return = frame->return_ptr; pr->pr_xfunction = frame->func; pr->pr_xstatement = frame->staddr; pr->pr_xtstr = frame->tstr; @@ -419,7 +421,7 @@ error_handler (void *data) } VISIBLE int -PR_CallFunction (progs_t *pr, func_t fnum) +PR_CallFunction (progs_t *pr, func_t fnum, pr_type_t *return_ptr) { bfunction_t *f; @@ -432,10 +434,14 @@ PR_CallFunction (progs_t *pr, func_t fnum) Sys_Printf ("Calling builtin %s @ %p\n", PR_GetString (pr, f->descriptor->name), f->func); } + pr_type_t *saved_return = pr->pr_return; + pr->pr_return = return_ptr; f->func (pr); + pr->pr_return = saved_return; return 0; } else { PR_EnterFunction (pr, f); + pr->pr_return = return_ptr; return 1; } } @@ -1461,7 +1467,7 @@ op_rcall: op_call: pr->pr_xfunction->profile += profile - startprofile; startprofile = profile; - PR_CallFunction (pr, OPA(uint)); + PR_CallFunction (pr, OPA(uint), pr->pr_return); st = pr->pr_statements + pr->pr_xstatement; break; case OP_DONE_v6p: @@ -3154,10 +3160,9 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth) function = mm->func_var; pr->pr_argc = 0; // op_c specifies the location for the return value if any - pr->pr_return = op_c; pr->pr_xfunction->profile += profile - startprofile; startprofile = profile; - PR_CallFunction (pr, function); + PR_CallFunction (pr, function, op_c); st = pr->pr_statements + pr->pr_xstatement; break; // 1 1010 @@ -3466,7 +3471,7 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum) } int exitdepth = pr->pr_depth; - if (!PR_CallFunction (pr, fnum)) { + if (!PR_CallFunction (pr, fnum, pr->pr_return)) { // called a builtin instead of progs code goto exit_program; } diff --git a/libs/ruamoko/rua_obj.c b/libs/ruamoko/rua_obj.c index aab7b4c0f..22a8b98e7 100644 --- a/libs/ruamoko/rua_obj.c +++ b/libs/ruamoko/rua_obj.c @@ -1291,7 +1291,7 @@ rua___obj_forward (progs_t *pr) P_PACKED (pr, pr_va_list_t, 3).count = argc; P_PACKED (pr, pr_va_list_t, 3).list = PR_SetPointer (pr, argv); PR_PushTempString (pr, args_block); - PR_CallFunction (pr, imp); + PR_CallFunction (pr, imp, pr->pr_return); return; } //FIXME ditto @@ -1303,7 +1303,7 @@ rua___obj_forward (progs_t *pr) P_POINTER (pr, 1) = PR_SetPointer (pr, err_sel); P_POINTER (pr, 2) = PR_SetPointer (pr, sel); pr->pr_argc = 3; - PR_CallFunction (pr, imp); + PR_CallFunction (pr, imp, pr->pr_return); return; } @@ -1321,7 +1321,7 @@ rua___obj_forward (progs_t *pr) P_POINTER (pr, 1) = PR_SetPointer (pr, err_sel); P_POINTER (pr, 2) = PR_SetTempString (pr, probj->msg->str); pr->pr_argc = 3; - PR_CallFunction (pr, imp); + PR_CallFunction (pr, imp, pr->pr_return); return; } @@ -1437,7 +1437,7 @@ rua_obj_msg_sendv (progs_t *pr) memcpy (&P_INT (pr, 2), params, count * sizeof (pr_type_t) * pr->pr_param_size); } - PR_CallFunction (pr, imp); + PR_CallFunction (pr, imp, pr->pr_return); } static void @@ -1544,7 +1544,7 @@ rua_obj_msgSend (progs_t *pr) PR_GetString (pr, object_get_class_name (probj, self)), PR_GetString (pr, probj->selector_names[_cmd->sel_id])); - PR_CallFunction (pr, imp); + PR_CallFunction (pr, imp, pr->pr_return); } static void @@ -1564,7 +1564,7 @@ rua_obj_msgSend_super (progs_t *pr) } pr->pr_params[0] = pr->pr_real_params[0]; P_POINTER (pr, 0) = super->self; - PR_CallFunction (pr, imp); + PR_CallFunction (pr, imp, pr->pr_return); } static void