[gamecode] Delay .ctor calls if debugging

This allows a debugger to do any symbol lookups and other preparations
between loading progs and the first code execution. .ctors are called as
per normal if debug_handler is not set.
This commit is contained in:
Bill Currie 2020-04-02 17:28:37 +09:00
parent f90613bc3a
commit c09f57c39e
3 changed files with 37 additions and 12 deletions

View file

@ -236,14 +236,24 @@ void PR_AddLoadFinishFunc (progs_t *pr, pr_load_func_t *func);
\return true for success, false for failure
Calls the first set of internal load functions followed by the supplied
symbol resolution function, if any (progs_t::resolve), the second set of
internal load functions. After that, any primary load functions are called
in order of registration followed by any \c .ctor functions in the progs,
then any secondary load functions the primary load functions registered
in \e reverse order of registration.
symbol resolution function, if any (progs_t::resolve), then the second set
of internal load functions. After that, any primary load functions are
called in order of registration, and if there is no debug handler,
PR_RunPostLoadFuncs() is called.
*/
int PR_RunLoadFuncs (progs_t *pr);
/** Run any progs-dependent load functions.
\param pr pointer to ::progs_t VM struct
\return true for success, false for failure
This means any \c .ctor functions in the progs, followed by any secondary
load functions registered by either the primary load functions or the
\.c ctor functions in \e reverse order of registration. This is called
automatically by PR_RunLoadFuncs() if there is no debug handler, otherwise
it is up to the host to call this function.
*/
int PR_RunPostLoadFuncs (progs_t *pr);
/** Validate the opcodes and statement addresses in the progs. This is an
internal load function.
\param pr pointer to ::progs_t VM struct

View file

@ -422,6 +422,12 @@ PR_RunLoadFuncs (progs_t *pr)
if (!pr->load_funcs[i] (pr))
return 0;
return 1;
}
VISIBLE int
PR_RunPostLoadFuncs (progs_t *pr)
{
if (!pr_run_ctors (pr))
return 0;
@ -449,8 +455,12 @@ PR_LoadProgs (progs_t *pr, const char *progsname)
if (!pr->progs)
return;
if (!PR_RunLoadFuncs (pr))
if (!PR_RunLoadFuncs (pr)) {
PR_Error (pr, "unable to load %s", progsname);
}
if (!pr->debug_handler && !PR_RunPostLoadFuncs (pr)) {
PR_Error (pr, "unable to load %s", progsname);
}
}
VISIBLE void

View file

@ -206,6 +206,17 @@ spawn_progs (qwaq_thread_t *thread)
Sys_Error ("couldn't load %s", name);
}
if ((dfunc = PR_FindFunction (pr, ".main"))
|| (dfunc = PR_FindFunction (pr, "main"))) {
thread->main_func = dfunc - pr->pr_functions;
} else {
PR_Undefined (pr, "function", "main");
}
if (!PR_RunPostLoadFuncs (pr)) {
PR_Error (pr, "unable to load %s", pr->progs_name);
}
PR_PushFrame (pr);
if (thread->args.size > 2) {
pr_argc = thread->args.size - 1;
@ -216,12 +227,6 @@ spawn_progs (qwaq_thread_t *thread)
pr_argv[i] = PR_SetTempString (pr, thread->args.a[1 + i]);
pr_argv[i] = 0;
if ((dfunc = PR_FindFunction (pr, ".main"))
|| (dfunc = PR_FindFunction (pr, "main"))) {
thread->main_func = dfunc - pr->pr_functions;
} else {
PR_Undefined (pr, "function", "main");
}
PR_RESET_PARAMS (pr);
P_INT (pr, 0) = pr_argc;
P_POINTER (pr, 1) = PR_SetPointer (pr, pr_argv);