From c09f57c39ed3fed8c812199904c66af7ad3d4ac4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 2 Apr 2020 17:28:37 +0900 Subject: [PATCH] [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. --- include/QF/progs.h | 20 +++++++++++++++----- libs/gamecode/pr_load.c | 12 +++++++++++- ruamoko/qwaq/builtins/main.c | 17 +++++++++++------ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index db969f6af..fd9d653f7 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -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 diff --git a/libs/gamecode/pr_load.c b/libs/gamecode/pr_load.c index dd405769a..6ef18cc15 100644 --- a/libs/gamecode/pr_load.c +++ b/libs/gamecode/pr_load.c @@ -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 diff --git a/ruamoko/qwaq/builtins/main.c b/ruamoko/qwaq/builtins/main.c index 077b4674f..491a35277 100644 --- a/ruamoko/qwaq/builtins/main.c +++ b/ruamoko/qwaq/builtins/main.c @@ -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);