[gamecode] Add PR_Shutdown for tearing down a VM

This is meant for a "permanent" tear-down before freeing the memory
holding the VM state or at program shutdown. As a consequence, builtin
sub-systems registering resources are now required to pass a "destroy"
function pointer that will be called just before the memory holding
those resources is freed by the VM resource manager (ie, the manager
owns the resource memory block, but each subsystem is responsible for
cleaning up any resources held within that block).

This even enhances thread-safety in rua_obj (there are some problems
with cmd, cvar, and gib).
This commit is contained in:
Bill Currie 2022-05-12 18:23:32 +09:00
parent b7b6d4ad12
commit 973ae0ad54
28 changed files with 334 additions and 85 deletions

View file

@ -61,6 +61,15 @@ typedef struct edict_s edict_t;
*/
void PR_Init (progs_t *pr);
/** Shut down the progs engine.
Shuts down only the specified progs engine. Frees resources allocated
during progs init.
\param pr The progs engine instance to shut down.
*/
void PR_Shutdown (progs_t *pr);
/** Initialize the Cvars for the progs engine. Call before calling PR_Init().
*/
void PR_Init_Cvars (void);
@ -1692,6 +1701,9 @@ void PR_Sprintf (progs_t *pr, struct dstring_s *result, const char *name,
*/
void PR_Resources_Init (progs_t *pr);
void PR_Resources_Shutdown (progs_t *pr);
void PR_Builtins_Shutdown (progs_t *pr);
/** Clear all resources before loading a new progs.
Calls the clear() callback of all registered resources.
@ -1706,17 +1718,23 @@ void PR_Resources_Clear (progs_t *pr);
\param name The name of the resource. Used for retrieving the
resource.
\param data The resource data.
\param clear Callback for performing any necessary cleanup. Called
by PR_Resources_Clear(). The parameters are the current
\param clear Callback for performing any necessary cleanup before
VM reuse. Called by PR_Resources_Clear(). The parameters
are the current VM (\p pr) and \p data.
\param destroy Callback for when the resource is about to be destryed
due to final VM shutdown. The parameters are the current
VM (\p pr) and \p data.
\note The name should be unique to the VM, but no checking is
done. If the name is not unique, the previous registered
resource will break. The name of the sub-system
registering the resource is a suitable name, and will
probably be unique.
\note During VM shutdown, \a clear is called (for all resources)
before \destroy is called.
*/
void PR_Resources_Register (progs_t *pr, const char *name, void *data,
void (*clear)(progs_t *, void *));
void (*clear)(progs_t *, void *),
void (*destroy)(progs_t *, void *));
/** Retrieve a resource registered with the VM.

View file

@ -102,6 +102,11 @@ bi_il_clear (progs_t *pr, void *_res)
il_data_reset (res);
}
static void
bi_il_destroy (progs_t *pr, void *_res)
{
}
static il_data_t * __attribute__((pure))
get_inputline (progs_t *pr, il_resources_t *res, int arg, const char *func)
{
@ -341,7 +346,7 @@ InputLine_Progs_Init (progs_t *pr)
{
il_resources_t *res = calloc (1, sizeof (il_resources_t));
PR_Resources_Register (pr, "InputLine", res, bi_il_clear);
PR_Resources_Register (pr, "InputLine", res, bi_il_clear, bi_il_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -158,6 +158,21 @@ PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins, void *data)
}
}
void
PR_Builtins_Shutdown (progs_t *pr)
{
for (size_t i = 0; i < pr->builtin_blocks->size; i++) {
free (pr->builtin_blocks->a[i]);
}
DARRAY_CLEAR (pr->builtin_blocks);
free (pr->builtin_blocks);
pr->builtin_blocks = 0;
Hash_DelTable (pr->builtin_hash);
pr->builtin_hash = 0;
Hash_DelTable (pr->builtin_num_hash);
pr->builtin_num_hash = 0;
}
VISIBLE builtin_t *
PR_FindBuiltin (progs_t *pr, const char *name)
{

View file

@ -391,6 +391,24 @@ pr_debug_clear (progs_t *pr, void *data)
}
}
static void
pr_debug_destroy (progs_t *pr, void *_res)
{
__auto_type res = (prdeb_resources_t *) _res;
dstring_delete (res->string);
dstring_delete (res->dva);
dstring_delete (res->line);
dstring_delete (res->dstr);
va_destroy_context (res->va);
Hash_DelTable (res->file_hash);
Hash_DelTable (res->debug_syms);
Hash_DelTable (res->compunits);
pr->pr_debug_resources = 0;
}
static file_t *
PR_Load_Source_File (progs_t *pr, const char *fname)
{
@ -1952,7 +1970,8 @@ PR_Debug_Init (progs_t *pr)
res->debug_syms = Hash_NewTable (509, def_get_key, 0, pr, pr->hashctx);
res->compunits = Hash_NewTable (509, compunit_get_key, 0, pr, pr->hashctx);
PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear);
PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear,
pr_debug_destroy);
pr->pr_debug_resources = res;
}

View file

@ -550,6 +550,27 @@ PR_Init (progs_t *pr)
pr->type_hash = Hash_NewTable (1021, type_get_key, 0, pr, pr->hashctx);
}
VISIBLE void
PR_Shutdown (progs_t *pr)
{
PR_Resources_Shutdown (pr);
PR_Builtins_Shutdown (pr);
free (pr->load_funcs);
free (pr->load_finish_funcs);
pr->num_load_funcs = pr->max_load_funcs = 0;
pr->num_load_finish_funcs = pr->max_load_finish_funcs = 0;
Hash_DelTable (pr->function_hash);
Hash_DelTable (pr->global_hash);
Hash_DelTable (pr->field_hash);
Hash_DelTable (pr->type_hash);
pr->function_hash = 0;
pr->global_hash = 0;
pr->field_hash = 0;
pr->type_hash = 0;
}
VISIBLE void
PR_Error (progs_t *pr, const char *error, ...)
{

View file

@ -42,6 +42,7 @@ struct pr_resource_s {
pr_resource_t *next;
void *data;
void (*clear)(progs_t *pr, void *data);
void (*destroy)(progs_t *pr, void *data);
};
static const char *
@ -68,9 +69,30 @@ PR_Resources_Clear (progs_t *pr)
}
}
VISIBLE void
PR_Resources_Shutdown (progs_t *pr)
{
// Clear resources first in case there are any cross-dependencies
PR_Resources_Clear (pr);
pr_resource_t *res = pr->resources;
while (res) {
pr_resource_t *t = res->next;
res->destroy (pr, res->data);
free (res->data);
free (res);
res = t;
}
pr->resources = 0;
Hash_DelTable (pr->resource_hash);
pr->resource_hash = 0;
}
VISIBLE void
PR_Resources_Register (progs_t *pr, const char *name, void *data,
void (*clear)(progs_t *, void *))
void (*clear)(progs_t *, void *),
void (*destroy)(progs_t *, void *))
{
pr_resource_t *res = malloc (sizeof (pr_resource_t));
if (!res)
@ -78,6 +100,7 @@ PR_Resources_Register (progs_t *pr, const char *name, void *data,
res->name = name;
res->data = data;
res->clear = clear;
res->destroy = destroy;
res->next = pr->resources;
pr->resources = res;
Hash_Add (pr->resource_hash, res);

View file

@ -232,6 +232,15 @@ pr_strings_clear (progs_t *pr, void *data)
pr->pr_xtstr = 0;
}
static void
pr_strings_destroy (progs_t *pr, void *_res)
{
__auto_type res = (prstr_resources_t *) _res;
dstring_delete (res->print_str);
Hash_DelTable (res->strref_hash);
pr->pr_string_resources = 0;
}
VISIBLE int
PR_LoadStrings (progs_t *pr)
{
@ -261,15 +270,7 @@ PR_LoadStrings (progs_t *pr)
res->ds_mem.realloc = pr_strings_realloc;
res->ds_mem.data = pr;
if (res->strref_hash) {
Hash_FlushTable (res->strref_hash);
} else {
res->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
res, pr->hashctx);
res->string_map = 0;
res->free_string_refs = 0;
res->dyn_str_size = 0;
}
Hash_FlushTable (res->strref_hash);
if (res->static_strings)
free (res->static_strings);
@ -1254,7 +1255,10 @@ PR_Strings_Init (progs_t *pr)
prstr_resources_t *res = calloc (1, sizeof (*res));
res->pr = pr;
res->print_str = dstring_new ();
res->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
res, pr->hashctx);
PR_Resources_Register (pr, "Strings", res, pr_strings_clear);
PR_Resources_Register (pr, "Strings", res, pr_strings_clear,
pr_strings_destroy);
pr->pr_string_resources = res;
}

View file

@ -112,6 +112,13 @@ bi_gib_builtin_clear (progs_t *progs, void *_res)
}
}
static void
bi_gib_builtin_destroy (progs_t *progs, void *_res)
{
//bi_gib_resources_t *res = (bi_gib_resources_t *) _res;
Hash_DelTable (bi_gib_builtins);
}
static void
bi_GIB_Builtin_Add (progs_t *pr, void *_res)
{
@ -194,9 +201,13 @@ GIB_Progs_Init (progs_t *pr)
bi_gib_resources_t *res = malloc (sizeof (bi_gib_resources_t));
res->builtins = 0;
if (bi_gib_builtins) {
Sys_Error ("GIB_Progs_Init: only one progs VM supported FIXME");
}
bi_gib_builtins = Hash_NewTable (1021, bi_gib_builtin_get_key,
bi_gib_builtin_free, 0, pr->hashctx);
PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear);
PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear,
bi_gib_builtin_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -41,13 +41,12 @@ typedef struct {
cbuf_t *cbuf;
} cbuf_resources_t;
static cbuf_t *
get_cbuf (progs_t *pr, int arg, const char *func)
static cbuf_t * __attribute__((pure))
_get_cbuf (progs_t *pr, cbuf_resources_t *res, int arg, const char *func)
{
cbuf_t *cbuf = 0;
if (arg == 0) {
cbuf_resources_t *res = PR_Resources_Find (pr, "Cbuf");
cbuf = res->cbuf;
} else {
PR_RunError (pr, "%s: Invalid cbuf_t", func);
@ -57,12 +56,13 @@ get_cbuf (progs_t *pr, int arg, const char *func)
return cbuf;
}
#define get_cbuf(pr, res, arg) _get_cbuf(pr, res, arg, __FUNCTION__)
static void
bi_Cbuf_AddText (progs_t *pr, void *data)
{
const char *text = P_GSTRING (pr, 0);
cbuf_t *cbuf = get_cbuf (pr, 0, __FUNCTION__);
cbuf_t *cbuf = get_cbuf (pr, data, 0);
Cbuf_AddText (cbuf, text);
}
@ -70,21 +70,21 @@ static void
bi_Cbuf_InsertText (progs_t *pr, void *data)
{
const char *text = P_GSTRING (pr, 0);
cbuf_t *cbuf = get_cbuf (pr, 0, __FUNCTION__);
cbuf_t *cbuf = get_cbuf (pr, data, 0);
Cbuf_InsertText (cbuf, text);
}
static void
bi_Cbuf_Execute (progs_t *pr, void *data)
{
cbuf_t *cbuf = get_cbuf (pr, 0, __FUNCTION__);
cbuf_t *cbuf = get_cbuf (pr, data, 0);
Cbuf_Execute (cbuf);
}
static void
bi_Cbuf_Execute_Sets (progs_t *pr, void *data)
{
cbuf_t *cbuf = get_cbuf (pr, 0, __FUNCTION__);
cbuf_t *cbuf = get_cbuf (pr, data, 0);
Cbuf_Execute_Sets (cbuf);
}
@ -93,6 +93,11 @@ bi_cbuf_clear (progs_t *pr, void *data)
{
}
static void
bi_cbuf_destroy (progs_t *pr, void *data)
{
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
@ -108,7 +113,7 @@ void
RUA_Cbuf_Init (progs_t *pr, int secure)
{
cbuf_resources_t *res = calloc (sizeof (cbuf_resources_t), 1);
PR_Resources_Register (pr, "Cbuf", res, bi_cbuf_clear);
PR_Resources_Register (pr, "Cbuf", res, bi_cbuf_clear, bi_cbuf_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -58,6 +58,7 @@ typedef struct {
} cmd_resources_t;
static hashtab_t *bi_cmds;
static int bi_cmds_refs;
static const char *
bi_cmd_get_key (const void *c, void *unused)
@ -123,6 +124,14 @@ bi_cmd_clear (progs_t *pr, void *data)
}
}
static void
bi_cmd_destroy (progs_t *pr, void *data)
{
if (!--bi_cmds_refs) {
Hash_DelTable (bi_cmds);
}
}
static void
bi_Cmd_Argc (progs_t *pr, void *data)
{
@ -162,10 +171,12 @@ RUA_Cmd_Init (progs_t *pr, int secure)
res->cmds = 0;
if (!bi_cmds)
if (!bi_cmds) {
bi_cmds = Hash_NewTable (1021, bi_cmd_get_key, bi_cmd_free, 0,
pr->hashctx);
}
bi_cmds_refs++;
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear);
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear, bi_cmd_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -76,6 +76,11 @@ bi_cvar_clear (progs_t *pr, void *_res)
}
}
static void
bi_cvar_destroy (progs_t *pr, void *_res)
{
}
static void
bi_Cvar_MakeAlias (progs_t *pr, void *_res)
{
@ -266,6 +271,6 @@ RUA_Cvar_Init (progs_t *pr, int secure)
cvar_resources_t *res = calloc (1, sizeof (cvar_resources_t));
res->aliases = 0;
PR_Resources_Register (pr, "Cvar", res, bi_cvar_clear);
PR_Resources_Register (pr, "Cvar", res, bi_cvar_clear, bi_cvar_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -382,6 +382,11 @@ bi_hash_clear (progs_t *pr, void *_res)
table_reset (res);
}
static void
bi_hash_destroy (progs_t *pr, void *_res)
{
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
@ -411,6 +416,6 @@ RUA_Hash_Init (progs_t *pr, int secure)
hash_resources_t *res = calloc (1, sizeof (hash_resources_t));
res->tabs = 0;
PR_Resources_Register (pr, "Hash", res, bi_hash_clear);
PR_Resources_Register (pr, "Hash", res, bi_hash_clear, bi_hash_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -480,6 +480,14 @@ bi_input_clear (progs_t *pr, void *_res)
Hash_FlushTable (res->cookies);
}
static void
bi_input_destroy (progs_t *pr, void *_res)
{
input_resources_t *res = _res;
Hash_DelTable (res->cookies);
delete_memsuper (res->cookie_super);
}
static uintptr_t
rua_in_hash_cookie (const void *_cookie, void *_res)
{
@ -513,7 +521,7 @@ RUA_Input_Init (progs_t *pr, int secure)
&res->hashctx);
Hash_SetHashCompare (res->cookies, rua_in_hash_cookie, rua_in_cmp_cookies);
PR_Resources_Register (pr, "input", res, bi_input_clear);
PR_Resources_Register (pr, "input", res, bi_input_clear, bi_input_destroy);
if (secure & 2) {
PR_RegisterBuiltins (pr, secure_builtins, res);
} else {

View file

@ -147,6 +147,11 @@ bi_mtwist_clear (progs_t *pr, void *_res)
state_reset (res);
}
static void
bi_mtwist_destroy (progs_t *pr, void *_res)
{
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
@ -164,6 +169,7 @@ RUA_Mersenne_Init (progs_t *pr, int secure)
{
mtwist_resources_t *res = calloc (1, sizeof (mtwist_resources_t));
PR_Resources_Register (pr, "Mersenne Twister", res, bi_mtwist_clear);
PR_Resources_Register (pr, "Mersenne Twister", res, bi_mtwist_clear,
bi_mtwist_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -103,6 +103,11 @@ bi_rua_model_clear (progs_t *pr, void *_res)
rua_model_handle_reset (res);
}
static void
bi_rua_model_destroy (progs_t *pr, void *_res)
{
}
static int
alloc_handle (rua_model_resources_t *res, model_t *model)
{
@ -177,6 +182,7 @@ RUA_Model_Init (progs_t *pr, int secure)
rua_model_resources_t *res = calloc (sizeof (rua_model_resources_t), 1);
res->pr = pr;
PR_Resources_Register (pr, "Model", res, bi_rua_model_clear);
PR_Resources_Register (pr, "Model", res, bi_rua_model_clear,
bi_rua_model_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -94,6 +94,11 @@ bi_msgbuf_clear (progs_t *pr, void *data)
msgbuf_reset (res);
}
static void
bi_msgbuf_destroy (progs_t *pr, void *_res)
{
}
static int
alloc_msgbuf (msgbuf_resources_t *res, byte *buf, int size)
{
@ -481,6 +486,7 @@ RUA_MsgBuf_Init (progs_t *pr, int secure)
{
msgbuf_resources_t *res = calloc (sizeof (msgbuf_resources_t), 1);
PR_Resources_Register (pr, "MsgBuf", res, bi_msgbuf_clear);
PR_Resources_Register (pr, "MsgBuf", res, bi_msgbuf_clear,
bi_msgbuf_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -124,6 +124,7 @@ typedef struct probj_resources_s {
hashtab_t *classes;
hashtab_t *protocols;
hashtab_t *load_methods;
obj_list *obj_list_free_list;
obj_list *unresolved_classes;
obj_list *unclaimed_categories;
obj_list *uninitialized_statics;
@ -175,27 +176,25 @@ get_dtable (probj_t *probj, const char *name, int index)
return dtable;
}
static obj_list *obj_list_free_list;
static obj_list *
obj_list_new (void)
obj_list_new (probj_t *probj)
{
int i;
obj_list *l;
if (!obj_list_free_list) {
obj_list_free_list = calloc (128, sizeof (obj_list));
if (!probj->obj_list_free_list) {
probj->obj_list_free_list = calloc (128, sizeof (obj_list));
for (i = 0; i < 127; i++)
obj_list_free_list[i].next = &obj_list_free_list[i + 1];
probj->obj_list_free_list[i].next = &probj->obj_list_free_list[i + 1];
}
l = obj_list_free_list;
obj_list_free_list = l->next;
l = probj->obj_list_free_list;
probj->obj_list_free_list = l->next;
l->next = 0;
return l;
}
static void
obj_list_free (obj_list *l)
obj_list_free (probj_t *probj, obj_list *l)
{
obj_list *e;
@ -204,29 +203,29 @@ obj_list_free (obj_list *l)
for (e = l; e->next; e = e->next)
;
e->next = obj_list_free_list;
obj_list_free_list = l;
e->next = probj->obj_list_free_list;
probj->obj_list_free_list = l;
}
static inline obj_list *
list_cons (void *data, obj_list *next)
list_cons (probj_t *probj, void *data, obj_list *next)
{
obj_list *l = obj_list_new ();
obj_list *l = obj_list_new (probj);
l->data = data;
l->next = next;
return l;
}
static inline void
list_remove (obj_list **list)
list_remove (probj_t *probj, obj_list **list)
{
if ((*list)->next) {
obj_list *l = *list;
*list = (*list)->next;
l->next = 0;
obj_list_free (l);
obj_list_free (probj, l);
} else {
obj_list_free (*list);
obj_list_free (probj, *list);
*list = 0;
}
}
@ -288,7 +287,7 @@ create_tree_of_subclasses_inherited_from (probj_t *probj, pr_class_t *bottom,
while (superclass != upper) {
tree = class_tree_new ();
tree->class = superclass;
tree->subclasses = list_cons (prev, tree->subclasses);
tree->subclasses = list_cons (probj, prev, tree->subclasses);
super_class = PR_GetString (pr, superclass->super_class);
superclass = (superclass->super_class ? Hash_Find (probj->classes,
super_class)
@ -323,7 +322,7 @@ _obj_tree_insert_class (probj_t *probj, class_tree *tree, pr_class_t *class)
}
node = class_tree_new ();
node->class = class;
tree->subclasses = list_cons (node, tree->subclasses);
tree->subclasses = list_cons (probj, node, tree->subclasses);
return tree;
}
if (!class_is_subclass_of_class (probj, class, tree->class))
@ -339,7 +338,7 @@ _obj_tree_insert_class (probj_t *probj, class_tree *tree, pr_class_t *class)
}
new_tree = create_tree_of_subclasses_inherited_from (probj, class,
tree->class);
tree->subclasses = list_cons (new_tree, tree->subclasses);
tree->subclasses = list_cons (probj, new_tree, tree->subclasses);
return tree;
}
@ -361,7 +360,8 @@ obj_tree_insert_class (probj_t *probj, pr_class_t *class)
}
if (!list_node) {
tree = _obj_tree_insert_class (probj, 0, class);
probj->class_tree_list = list_cons (tree, probj->class_tree_list);
probj->class_tree_list = list_cons (probj, tree,
probj->class_tree_list);
}
}
@ -584,7 +584,7 @@ sel_register_typed_name (probj_t *probj, const char *name, const char *types,
sel->sel_id = index;
sel->sel_types = PR_SetString (pr, types);
l = obj_list_new ();
l = obj_list_new (probj);
l->data = sel;
l->next = probj->selector_sels[index];
probj->selector_sels[index] = l;
@ -700,7 +700,7 @@ obj_init_protocols (probj_t *probj, pr_protocol_list_t *protos)
return;
if (!(proto_class = Hash_Find (probj->classes, "Protocol"))) {
probj->unclaimed_proto_list = list_cons (protos,
probj->unclaimed_proto_list = list_cons (probj, protos,
probj->unclaimed_proto_list);
return;
}
@ -821,7 +821,7 @@ obj_send_load (probj_t *probj)
pr_class_t *class = probj->unresolved_classes->data;
const char *super_class = PR_GetString (pr, class->super_class);
while (Hash_Find (probj->classes, super_class)) {
list_remove (&probj->unresolved_classes);
list_remove (probj, &probj->unresolved_classes);
if (probj->unresolved_classes) {
class = probj->unresolved_classes->data;
super_class = PR_GetString (pr, class->super_class);
@ -842,12 +842,12 @@ obj_send_load (probj_t *probj)
send_load);
obj_postorder_traverse (probj, probj->class_tree_list->data, 0,
obj_destroy_class_tree_node);
list_remove (&probj->class_tree_list);
list_remove (probj, &probj->class_tree_list);
}
//XXX callback
//for (m = probj->module_list; m; m = m->next)
// obj_create_classes_tree (probj, m->data);
obj_list_free (probj->module_list);
obj_list_free (probj, probj->module_list);
probj->module_list = 0;
}
@ -1090,10 +1090,9 @@ obj_verror (probj_t *probj, pr_id_t *object, int code, const char *fmt, int coun
{
progs_t *pr = probj->pr;
__auto_type class = &G_STRUCT (pr, pr_class_t, object->class_pointer);
dstring_t *dstr = dstring_newstr ();
PR_Sprintf (pr, dstr, "obj_verror", fmt, count, args);
PR_RunError (pr, "%s: %s", PR_GetString (pr, class->name), dstr->str);
PR_Sprintf (pr, probj->msg, "obj_verror", fmt, count, args);
PR_RunError (pr, "%s: %s", PR_GetString (pr, class->name), probj->msg->str);
}
static void
@ -1152,7 +1151,7 @@ obj_init_statics (probj_t *probj)
}
if (initialized) {
list_remove (cell);
list_remove (probj, cell);
} else {
cell = &(*cell)->next;
}
@ -1188,7 +1187,7 @@ rua___obj_exec_class (progs_t *pr, void *data)
symtab->defs[symtab->cls_def_cnt
+ symtab->cat_def_cnt] ? "yes" : "no");
probj->module_list = list_cons (module, probj->module_list);
probj->module_list = list_cons (probj, module, probj->module_list);
sel = &G_STRUCT (pr, pr_sel_t, symtab->refs);
for (i = 0; i < symtab->sel_ref_cnt; i++) {
@ -1242,7 +1241,7 @@ rua___obj_exec_class (progs_t *pr, void *data)
}
if (class->super_class && !Hash_Find (probj->classes, super_class))
probj->unresolved_classes = list_cons (class,
probj->unresolved_classes = list_cons (probj, class,
probj->unresolved_classes);
}
@ -1265,14 +1264,14 @@ rua___obj_exec_class (progs_t *pr, void *data)
finish_category (probj, category, class);
} else {
probj->unclaimed_categories
= list_cons (category, probj->unclaimed_categories);
= list_cons (probj, category, probj->unclaimed_categories);
}
}
if (*ptr) {
Sys_MaskPrintf (SYS_rua_obj, "Static instances lists: %x\n", *ptr);
probj->uninitialized_statics
= list_cons (&G_STRUCT (pr, pr_ptr_t, *ptr),
= list_cons (probj, &G_STRUCT (pr, pr_ptr_t, *ptr),
probj->uninitialized_statics);
}
if (probj->uninitialized_statics) {
@ -1285,7 +1284,7 @@ rua___obj_exec_class (progs_t *pr, void *data)
pr_class_t *class = Hash_Find (probj->classes, class_name);
if (class) {
list_remove (cell);
list_remove (probj, cell);
finish_category (probj, category, class);
} else {
cell = &(*cell)->next;
@ -1296,7 +1295,7 @@ rua___obj_exec_class (progs_t *pr, void *data)
&& Hash_Find (probj->classes, "Protocol")) {
for (cell = &probj->unclaimed_proto_list; *cell; ) {
obj_init_protocols (probj, (*cell)->data);
list_remove (cell);
list_remove (probj, cell);
}
}
@ -2044,14 +2043,13 @@ rua__i_Object_error_error_ (progs_t *pr, void *data)
probj_t *probj = pr->pr_objective_resources;
pr_id_t *self = &P_STRUCT (pr, pr_id_t, 0);
const char *fmt = P_GSTRING (pr, 2);
dstring_t *dstr = dstring_new ();
int count = pr->pr_argc - 3;
pr_type_t **args = &pr->pr_params[3];
dsprintf (dstr, "error: %s (%s)\n%s",
dsprintf (probj->msg, "error: %s (%s)\n%s",
PR_GetString (pr, object_get_class_name (probj, self)),
object_is_instance (probj, self) ? "instance" : "class", fmt);
obj_verror (probj, self, 0, dstr->str, count, args);
obj_verror (probj, self, 0, probj->msg->str, count, args);
}
static int
@ -2281,7 +2279,7 @@ rua_obj_cleanup (progs_t *pr, void *data)
probj->available_selectors = 0;
probj->selector_block = 0;
for (i = 0; i < probj->selector_index_max; i++) {
obj_list_free (probj->selector_sels[i]);
obj_list_free (probj, probj->selector_sels[i]);
probj->selector_sels[i] = 0;
probj->selector_names[i] = 0;
}
@ -2302,6 +2300,18 @@ rua_obj_cleanup (progs_t *pr, void *data)
probj->class_tree_list = 0;
}
static void
rua_obj_destroy (progs_t *pr, void *_res)
{
probj_t *probj = _res;
dstring_delete (probj->msg);
Hash_DelTable (probj->selector_hash);
Hash_DelTable (probj->classes);
Hash_DelTable (probj->protocols);
Hash_DelTable (probj->load_methods);
}
void
RUA_Obj_Init (progs_t *pr, int secure)
{
@ -2318,7 +2328,8 @@ RUA_Obj_Init (progs_t *pr, int secure)
Hash_SetHashCompare (probj->load_methods, load_methods_get_hash,
load_methods_compare);
PR_Resources_Register (pr, "RUA_ObjectiveQuakeC", probj, rua_obj_cleanup);
PR_Resources_Register (pr, "RUA_ObjectiveQuakeC", probj, rua_obj_cleanup,
rua_obj_destroy);
PR_RegisterBuiltins (pr, obj_methods, probj);
PR_AddLoadFunc (pr, rua_obj_init_runtime);

View file

@ -106,6 +106,13 @@ bi_plist_clear (progs_t *pr, void *_res)
plist_reset (res);
}
static void
bi_plist_destroy (progs_t *pr, void *_res)
{
__auto_type res = (plist_resources_t *) _res;
Hash_DelTable (res->plist_tab);
}
static inline int
plist_handle (plist_resources_t *res, plitem_t *plitem)
{
@ -486,6 +493,6 @@ RUA_Plist_Init (progs_t *pr, int secure)
res->plist_tab = Hash_NewTable (1021, 0, 0, 0, pr->hashctx);
Hash_SetHashCompare (res->plist_tab, plist_get_hash, plist_compare);
PR_Resources_Register (pr, "plist", res, bi_plist_clear);
PR_Resources_Register (pr, "plist", res, bi_plist_clear, bi_plist_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -95,6 +95,11 @@ bi_qfile_clear (progs_t *pr, void *_res)
handle_reset (res);
}
static void
bi_qfile_destroy (progs_t *pr, void *_res)
{
}
static int
alloc_handle (qfile_resources_t *res, QFile *file)
{
@ -401,7 +406,7 @@ RUA_QFile_Init (progs_t *pr, int secure)
{
qfile_resources_t *res = calloc (sizeof (qfile_resources_t), 1);
PR_Resources_Register (pr, "QFile", res, bi_qfile_clear);
PR_Resources_Register (pr, "QFile", res, bi_qfile_clear, bi_qfile_destroy);
if (secure) {
PR_RegisterBuiltins (pr, secure_builtins, res);
} else {

View file

@ -655,6 +655,11 @@ bi_scene_clear (progs_t *pr, void *_res)
}
}
static void
bi_scene_destroy (progs_t *pr, void *_res)
{
}
void
RUA_Scene_Init (progs_t *pr, int secure)
{
@ -662,6 +667,6 @@ RUA_Scene_Init (progs_t *pr, int secure)
res->pr = pr;
PR_Resources_Register (pr, "Scene", res, bi_scene_clear);
PR_Resources_Register (pr, "Scene", res, bi_scene_clear, bi_scene_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -91,6 +91,11 @@ bi_script_clear (progs_t *pr, void *_res)
script_reset (res);
}
static void
bi_script_destroy (progs_t *pr, void *_res)
{
}
static void
bi_Script_New (progs_t *pr, void *_res)
{
@ -206,6 +211,7 @@ RUA_Script_Init (progs_t *pr, int secure)
{
script_resources_t *res = calloc (1, sizeof (script_resources_t));
PR_Resources_Register (pr, "Script", res, bi_script_clear);
PR_Resources_Register (pr, "Script", res, bi_script_clear,
bi_script_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -803,6 +803,11 @@ res_set_clear (progs_t *pr, void *_res)
res_set_iter_reset (res);
}
static void
res_set_destroy (progs_t *pr, void *_res)
{
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
@ -863,6 +868,6 @@ RUA_Set_Init (progs_t *pr, int secure)
set_resources_t *res = calloc (1, sizeof (set_resources_t));
res->sets = 0;
PR_Resources_Register (pr, "Set", res, res_set_clear);
PR_Resources_Register (pr, "Set", res, res_set_clear, res_set_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -327,6 +327,13 @@ bi_draw_clear (progs_t *pr, void *_res)
Hash_FlushTable (res->pic_hash);
}
static void
bi_draw_destroy (progs_t *pr, void *_res)
{
draw_resources_t *res = (draw_resources_t *) _res;
Hash_DelTable (res->pic_hash);
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
@ -354,6 +361,6 @@ R_Progs_Init (progs_t *pr)
draw_resources_t *res = calloc (1, sizeof (draw_resources_t));
res->pic_hash = Hash_NewTable (61, bi_draw_get_key, 0, 0, pr->hashctx);
PR_Resources_Register (pr, "Draw", res, bi_draw_clear);
PR_Resources_Register (pr, "Draw", res, bi_draw_clear, bi_draw_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -1861,6 +1861,11 @@ bi_curses_clear (progs_t *pr, void *_res)
panel_reset (res);
}
static void
bi_curses_destroy (progs_t *pr, void *_res)
{
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
@ -1963,7 +1968,8 @@ BI_Curses_Init (progs_t *pr)
qwaq_init_pipe (&res->commands);
qwaq_init_pipe (&res->results);
PR_Resources_Register (pr, "curses", res, bi_curses_clear);
PR_Resources_Register (pr, "curses", res, bi_curses_clear,
bi_curses_destroy);
PR_RegisterBuiltins (pr, builtins, res);
Sys_RegisterShutdown (bi_shutdown, pr);
}

View file

@ -164,6 +164,11 @@ qwaq_debug_clear (progs_t *pr, void *_res)
target_reset (debug);
}
static void
qwaq_debug_destroy (progs_t *pr, void *_res)
{
}
static void
qwaq_target_clear (progs_t *pr, void *_res)
{
@ -173,6 +178,11 @@ qwaq_target_clear (progs_t *pr, void *_res)
}
}
static void
qwaq_target_destroy (progs_t *pr, void *_res)
{
}
static int
qwaq_target_load (progs_t *pr)
{
@ -718,7 +728,8 @@ QWAQ_Debug_Init (progs_t *pr)
debug->input = PR_Resources_Find (pr, "input");
PR_AddLoadFunc (pr, qwaq_debug_load);
PR_Resources_Register (pr, "qwaq-debug", debug, qwaq_debug_clear);
PR_Resources_Register (pr, "qwaq-debug", debug, qwaq_debug_clear,
qwaq_debug_destroy);
PR_RegisterBuiltins (pr, builtins, debug);
}
@ -726,5 +737,6 @@ void
QWAQ_DebugTarget_Init (progs_t *pr)
{
PR_AddLoadFunc (pr, qwaq_target_load);
PR_Resources_Register (pr, "qwaq-target", 0, qwaq_target_clear);
PR_Resources_Register (pr, "qwaq-target", 0, qwaq_target_clear,
qwaq_target_destroy);
}

View file

@ -1017,6 +1017,11 @@ qwaq_ebresources_clear (progs_t *pr, void *_res)
editbuffer_reset (res);
}
static void
qwaq_ebresources_destroy (progs_t *pr, void *_res)
{
}
#define bi(x,n,np,params...) {#x, bi_##x, n, np, {params}}
#define p(type) PR_PARAM(type)
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
@ -1067,6 +1072,7 @@ QWAQ_EditBuffer_Init (progs_t *pr)
qwaq_ebresources_t *res = calloc (sizeof (*res), 1);
res->pr = pr;
PR_Resources_Register (pr, "qwaq-editbuffer", res, qwaq_ebresources_clear);
PR_Resources_Register (pr, "qwaq-editbuffer", res, qwaq_ebresources_clear,
qwaq_ebresources_destroy);
PR_RegisterBuiltins (pr, builtins, res);
}

View file

@ -197,6 +197,11 @@ qwaq_thread_clear (progs_t *pr, void *_thread)
{
}
static void
qwaq_thread_destroy (progs_t *pr, void *_res)
{
}
static progs_t *
create_progs (qwaq_thread_t *thread)
{
@ -212,7 +217,8 @@ create_progs (qwaq_thread_t *thread)
pr_debug = 2;
pr_boundscheck = 0;
PR_Init (pr);
PR_Resources_Register (pr, "qwaq_thread", thread, qwaq_thread_clear);
PR_Resources_Register (pr, "qwaq_thread", thread, qwaq_thread_clear,
qwaq_thread_destroy);
RUA_Init (pr, thread->rua_security);
common_builtins_init (pr);
while (*funcs) {

View file

@ -889,6 +889,11 @@ bi_input_clear (progs_t *pr, void *_res)
}
}
static void
bi_input_destroy (progs_t *pr, void *_res)
{
}
static void
bi_input_shutdown (void *_pr)
{
@ -915,7 +920,7 @@ BI_TermInput_Init (progs_t *pr)
qwaq_init_cond (&res->events.cond);
PR_Resources_Register (pr, "input", res, bi_input_clear);
PR_Resources_Register (pr, "input", res, bi_input_clear, bi_input_destroy);
PR_RegisterBuiltins (pr, builtins, res);
Sys_RegisterShutdown (bi_input_shutdown, pr);
}