From 385a90e8fbbecb2d95743214d9402ea31a608528 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Aug 2003 06:15:19 +0000 Subject: [PATCH] correct pr_symtab_t to include the pointer to the array of selectors used in the module. Unfortunatly, this requires a version bump on both qfo and progs files due to the changes structure layout. --- include/QF/pr_comp.h | 2 +- include/QF/pr_obj.h | 1 + libs/gamecode/engine/pr_obj.c | 54 ++++---------- tools/qfcc/include/def.h | 1 + tools/qfcc/include/emit.h | 8 +++ tools/qfcc/include/method.h | 12 +++- tools/qfcc/include/obj_file.h | 2 +- tools/qfcc/source/class.c | 27 ++++--- tools/qfcc/source/def.c | 2 +- tools/qfcc/source/expr.c | 10 ++- tools/qfcc/source/immediate.c | 2 +- tools/qfcc/source/method.c | 127 ++++++++++++++++++++++----------- tools/qfprogs/source/modules.c | 18 +++++ 13 files changed, 166 insertions(+), 100 deletions(-) diff --git a/include/QF/pr_comp.h b/include/QF/pr_comp.h index 2a0fa76bb..e0e69ce45 100644 --- a/include/QF/pr_comp.h +++ b/include/QF/pr_comp.h @@ -350,7 +350,7 @@ typedef struct pr_va_list_s { } pr_va_list_t; #define PROG_ID_VERSION 6 -#define PROG_VERSION 0x00fff003 // MMmmmRRR 0.fff.003 (hex) +#define PROG_VERSION 0x00fff004 // MMmmmRRR 0.fff.004 (hex) typedef struct dprograms_s { unsigned int version; diff --git a/include/QF/pr_obj.h b/include/QF/pr_obj.h index 167916a05..243892d6b 100644 --- a/include/QF/pr_obj.h +++ b/include/QF/pr_obj.h @@ -147,6 +147,7 @@ typedef struct pr_ivar_s pr_ivar_t; typedef struct pr_symtab_s { int sel_ref_cnt; + pointer_t refs; // pr_sel_t int cls_def_cnt; int cat_def_cnt; pointer_t defs[1]; // variable array of class pointers then diff --git a/libs/gamecode/engine/pr_obj.c b/libs/gamecode/engine/pr_obj.c index 4bc06d569..ff5b19de3 100644 --- a/libs/gamecode/engine/pr_obj.c +++ b/libs/gamecode/engine/pr_obj.c @@ -194,21 +194,28 @@ pr___obj_exec_class (progs_t *pr) { pr_module_t *module = &P_STRUCT (pr, pr_module_t, 0); pr_symtab_t *symtab; + pr_sel_t *sel; pointer_t *ptr; int i; - //int d = developer->int_val; + int d = developer->int_val; if (!module) return; - //developer->int_val = 1; + developer->int_val = 1; symtab = &G_STRUCT (pr, pr_symtab_t, module->symtab); if (!symtab) return; - Sys_DPrintf ("Initializing %s module with symtab @ %d : %d class%s and %d " - "categor%s\n", + Sys_DPrintf ("Initializing %s module\n" + "symtab @ %d : %d selector%s, %d class%s and %d categor%s\n", PR_GetString (pr, module->name), module->symtab, + symtab->sel_ref_cnt, symtab->sel_ref_cnt == 1 ? "" : "s", symtab->cls_def_cnt, symtab->cls_def_cnt == 1 ? "" : "es", symtab->cat_def_cnt, symtab->cat_def_cnt == 1 ? "y" : "ies"); + sel = &G_STRUCT (pr, pr_sel_t, symtab->refs); + for (i = 0; i < symtab->sel_ref_cnt; i++) { + Sys_DPrintf (" %s\n", PR_GetString (pr, sel->sel_id)); + sel++; + } ptr = symtab->defs; for (i = 0; i < symtab->cls_def_cnt; i++) { pr_class_t *class = &G_STRUCT (pr, pr_class_t, *ptr); @@ -244,6 +251,7 @@ pr___obj_exec_class (progs_t *pr) Hash_AddElement (pr->categories, category); ptr++; } + developer->int_val = d; } //==================================================================== @@ -515,31 +523,6 @@ pr_sel_get_uid (progs_t *pr) PR_RunError (pr, "%s, not implemented", __FUNCTION__); } -static void -pr_sel_get_any_uid (progs_t *pr) -{ - //const char *name = P_GSTRING (pr, 0); - //XXX - PR_RunError (pr, "%s, not implemented", __FUNCTION__); -} - -static void -pr_sel_get_any_typed_uid (progs_t *pr) -{ - //const char *name = P_GSTRING (pr, 0); - //XXX - PR_RunError (pr, "%s, not implemented", __FUNCTION__); -} - -static void -pr_sel_get_typed_uid (progs_t *pr) -{ - //const char *name = P_GSTRING (pr, 0); - //const char *type = P_GSTRING (pr, 1); - //XXX - PR_RunError (pr, "%s, not implemented", __FUNCTION__); -} - static void pr_sel_register_name (progs_t *pr) { @@ -548,15 +531,6 @@ pr_sel_register_name (progs_t *pr) PR_RunError (pr, "%s, not implemented", __FUNCTION__); } -static void -pr_sel_register_typed_name (progs_t *pr) -{ - //const char *name = P_GSTRING (pr, 0); - //const char *type = P_GSTRING (pr, 1); - //XXX - PR_RunError (pr, "%s, not implemented", __FUNCTION__); -} - static void pr_sel_is_mapped (progs_t *pr) { @@ -907,11 +881,7 @@ static struct { {"sel_get_name", pr_sel_get_name}, {"sel_get_type", pr_sel_get_type}, {"sel_get_uid", pr_sel_get_uid}, - {"sel_get_any_uid", pr_sel_get_any_uid}, - {"sel_get_any_typed_uid", pr_sel_get_any_typed_uid}, - {"sel_get_typed_uid", pr_sel_get_typed_uid}, {"sel_register_name", pr_sel_register_name}, - {"sel_register_typed_name", pr_sel_register_typed_name}, {"sel_is_mapped", pr_sel_is_mapped}, {"class_get_class_method", pr_class_get_class_method}, diff --git a/tools/qfcc/include/def.h b/tools/qfcc/include/def.h index 16422d147..e63e077f4 100644 --- a/tools/qfcc/include/def.h +++ b/tools/qfcc/include/def.h @@ -118,6 +118,7 @@ def_t *field_def (const char *name); def_t *get_def (struct type_s *type, const char *name, scope_t *scope, storage_class_t storage); def_t *new_def (struct type_s *type, const char *name, scope_t *scope); +void set_storage_bits (def_t *def, storage_class_t storage); int new_location (struct type_s *type, defspace_t *space); void free_location (def_t *def); def_t *get_tempdef (struct type_s *type, scope_t *scope); diff --git a/tools/qfcc/include/emit.h b/tools/qfcc/include/emit.h index 0bda1ab05..e79a5e6a9 100644 --- a/tools/qfcc/include/emit.h +++ b/tools/qfcc/include/emit.h @@ -63,4 +63,12 @@ void emit_expr (struct expr_s *e); reloc_def_def (d, POINTER_OFS (&(dest))); \ } while (0) +#define EMIT_DEF_OFS(dest,def) \ + do { \ + def_t *d = (def); \ + (dest) = d ? d->ofs : 0; \ + if (d) \ + reloc_def_def_ofs (d, POINTER_OFS (&(dest))); \ + } while (0) + #endif//__emit_h diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index 75890be47..27f02b850 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -46,6 +46,12 @@ typedef struct method_s { char *types; } method_t; +typedef struct selector_s { + const char *name; + const char *types; + int index; +} selector_t; + typedef struct methodlist_s { method_t *head; method_t **tail; @@ -82,7 +88,9 @@ method_t *find_method (const char *sel_name); void selector_name (struct dstring_s *sel_id, keywordarg_t *selector); void selector_types (struct dstring_s *sel_types, keywordarg_t *selector); -struct def_s *selector_def (const char *sel_id, const char *sel_types); +int selector_index (const char *sel_id, const char *sel_types); +selector_t *get_selector (struct expr_s *sel); +struct def_s *emit_selectors(void); struct def_s *emit_methods (methodlist_t *methods, const char *name, int instance); @@ -91,4 +99,6 @@ void clear_selectors (void); struct expr_s *method_check_params (method_t *method, struct expr_s *args); +extern struct hashtab_s *known_methods; + #endif//__method_h diff --git a/tools/qfcc/include/obj_file.h b/tools/qfcc/include/obj_file.h index 0838694ce..9a6cc9c57 100644 --- a/tools/qfcc/include/obj_file.h +++ b/tools/qfcc/include/obj_file.h @@ -37,7 +37,7 @@ #include "QF/quakeio.h" #define QFO "QFO" -#define QFO_VERSION 0x00001004 // MMmmmRRR 0.001.004 (hex) +#define QFO_VERSION 0x00001005 // MMmmmRRR 0.001.005 (hex) typedef struct qfo_header_s { char qfo[4]; diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index a18b55450..d26d7e65b 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -447,8 +447,7 @@ class_find_method (class_type_t *class_type, method_t *method) method_t * class_message_response (class_t *class, int class_msg, expr_t *sel) { - pr_sel_t *selector; - char *sel_name; + selector_t *selector; method_t *m; class_t *c = class; category_t *cat; @@ -457,33 +456,32 @@ class_message_response (class_t *class, int class_msg, expr_t *sel) error (sel, "not a selector"); return 0; } - selector = &G_STRUCT (pr_sel_t, POINTER_VAL (sel->e.pointer)); - sel_name = G_GETSTR (selector->sel_id); + selector = get_selector (sel); if (class->type == &type_id) { - m = find_method (sel_name); + m = find_method (selector->name); if (m) return m; warning (sel, "could not find method for %c%s", class_msg ? '+' : '-', - sel_name); + selector->name); return 0; } else { while (c) { if (c->methods) { for (cat = c->categories; cat; cat = cat->next) { for (m = cat->methods->head; m; m = m->next) { - if (strcmp (sel_name, m->name) == 0) + if (strcmp (selector->name, m->name) == 0) return m; } } for (m = c->methods->head; m; m = m->next) { - if (strcmp (sel_name, m->name) == 0) + if (strcmp (selector->name, m->name) == 0) return m; } } c = c->super_class; } warning (sel, "%s does not respond to %c%s", class->name, - class_msg ? '+' : '-', sel_name); + class_msg ? '+' : '-', selector->name); } return 0; } @@ -636,6 +634,7 @@ class_finish_module (void) int num_classes = 0; int num_categories = 0; int i; + def_t *selector_table_def; struct_t *symtab_type; def_t *symtab_def; pr_symtab_t *symtab; @@ -647,6 +646,7 @@ class_finish_module (void) function_t *init_func; expr_t *init_expr; + selector_table_def = emit_selectors (); if (class_hash) { classes = (class_t **) Hash_GetList (class_hash); for (cl = classes; *cl; cl++) @@ -659,11 +659,12 @@ class_finish_module (void) if ((*ca)->def && !(*ca)->def->external) num_categories++; } - if (!num_classes && !num_categories) + if (!selector_table_def && !num_classes && !num_categories) return; symtab_type = get_struct (0, 1); init_struct (symtab_type, new_type (), str_struct, 0); new_struct_field (symtab_type, &type_integer, "sel_ref_cnt", vis_public); + new_struct_field (symtab_type, &type_SEL, "refs", vis_public); new_struct_field (symtab_type, &type_integer, "cls_def_cnt", vis_public); new_struct_field (symtab_type, &type_integer, "cat_def_cnt", vis_public); for (i = 0; i < num_classes + num_categories; i++) @@ -673,6 +674,10 @@ class_finish_module (void) symtab_def->initialized = symtab_def->constant = 1; symtab_def->nosave = 1; symtab = &G_STRUCT (pr_symtab_t, symtab_def->ofs); + if (selector_table_def) { + symtab->sel_ref_cnt = selector_table_def->type->num_parms; + EMIT_DEF (symtab->refs, selector_table_def); + } symtab->cls_def_cnt = num_classes; symtab->cat_def_cnt = num_categories; def_ptr = symtab->defs; @@ -698,7 +703,7 @@ class_finish_module (void) module_def->nosave = 1; module = &G_STRUCT (pr_module_t, module_def->ofs); module->size = type_size (type_module); - EMIT_STRING (module->name, options.output_file); + EMIT_STRING (module->name, G_GETSTR (pr.source_file)); EMIT_DEF (module->symtab, symtab_def); exec_class_def = get_def (&type_obj_exec_class, "__obj_exec_class", diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index c475c4f28..eb7095c68 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -156,7 +156,7 @@ new_scope (scope_type type, defspace_t *space, scope_t *parent) return scope; } -static void +void set_storage_bits (def_t *def, storage_class_t storage) { switch (storage) { diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index c060c738f..d68c66cdd 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2473,16 +2473,22 @@ selector_expr (keywordarg_t *selector) dstring_t *sel_id = dstring_newstr (); dstring_t *sel_types = dstring_newstr (); expr_t *sel; + def_t *sel_def; + int index; selector = copy_keywordargs (selector); selector = (keywordarg_t *) reverse_params ((param_t *) selector); selector_name (sel_id, selector); selector_types (sel_types, selector); //printf ("'%s' '%s'\n", sel_id->str, sel_types->str); - sel = new_def_expr (selector_def (sel_id->str, sel_types->str)); + index = selector_index (sel_id->str, sel_types->str); + index *= type_size (type_SEL.aux_type); + sel_def = get_def (type_SEL.aux_type, "_OBJ_SELECTOR_TABLE", pr.scope, + st_extern); + sel = new_def_expr (sel_def); dstring_delete (sel_id); dstring_delete (sel_types); - return address_expr (sel, 0, 0); + return address_expr (sel, new_short_expr (index), 0); } expr_t * diff --git a/tools/qfcc/source/immediate.c b/tools/qfcc/source/immediate.c index d3ad25db0..42ab7f4fc 100644 --- a/tools/qfcc/source/immediate.c +++ b/tools/qfcc/source/immediate.c @@ -274,7 +274,7 @@ ReuseConstant (expr_t *expr, def_t *def) break; case ex_pointer: if (e.e.pointer.def) - EMIT_DEF (G_INT (cn->ofs), e.e.pointer.def); + EMIT_DEF_OFS (G_INT (cn->ofs), e.e.pointer.def); break; default: break; diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index c2d3314ba..acfed1e9c 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -266,63 +266,107 @@ selector_types (dstring_t *sel_types, keywordarg_t *selector) dstring_clearstr (sel_types); } -typedef struct { - string_t sel_id; - string_t sel_types; - def_t *def; -} sel_def_t; - -static hashtab_t *sel_def_hash; +static hashtab_t *sel_hash; +static hashtab_t *sel_index_hash; +static int sel_index; static unsigned long -sel_def_get_hash (void *_sel_def, void *unused) +sel_get_hash (void *_sel, void *unused) { - sel_def_t *sel_def = (sel_def_t*)_sel_def; + selector_t *sel = (selector_t *) _sel; unsigned long hash; - hash = Hash_String (G_GETSTR (sel_def->sel_id)) - ^ Hash_String (G_GETSTR (sel_def->sel_types)); + hash = Hash_String (sel->name) ^ Hash_String (sel->types); return hash; } static int -sel_def_compare (void *_sd1, void *_sd2, void *unused) +sel_compare (void *_s1, void *_s2, void *unused) { - sel_def_t *sd1 = (sel_def_t*)_sd1; - sel_def_t *sd2 = (sel_def_t*)_sd2; + selector_t *s1 = (selector_t *) _s1; + selector_t *s2 = (selector_t *) _s2; int cmp; - cmp = strcmp (G_GETSTR (sd1->sel_id), G_GETSTR (sd2->sel_id)) == 0; + cmp = strcmp (s1->name, s2->name) == 0; if (cmp) - cmp = strcmp (G_GETSTR (sd1->sel_types), - G_GETSTR (sd2->sel_types)) == 0; + cmp = strcmp (s1->types, s2->types) == 0; return cmp; } -def_t * -selector_def (const char *sel_id, const char *sel_types) +static unsigned long +sel_index_get_hash (void *_sel, void *unused) { - sel_def_t _sel_def = {ReuseString (sel_id), ReuseString (sel_types), 0}; - sel_def_t *sel_def = &_sel_def; + selector_t *sel = (selector_t *) _sel; + return sel->index; +} - if (!sel_def_hash) { - sel_def_hash = Hash_NewTable (1021, 0, 0, 0); - Hash_SetHashCompare (sel_def_hash, sel_def_get_hash, sel_def_compare); +static int +sel_index_compare (void *_s1, void *_s2, void *unused) +{ + selector_t *s1 = (selector_t *) _s1; + selector_t *s2 = (selector_t *) _s2; + return s1->index == s2->index; +} + +int +selector_index (const char *sel_id, const char *sel_types) +{ + selector_t _sel = {save_string (sel_id), save_string (sel_types), 0}; + selector_t *sel = &_sel; + + if (!sel_hash) { + sel_hash = Hash_NewTable (1021, 0, 0, 0); + Hash_SetHashCompare (sel_hash, sel_get_hash, sel_compare); + sel_index_hash = Hash_NewTable (1021, 0, 0, 0); + Hash_SetHashCompare (sel_index_hash, sel_index_get_hash, + sel_index_compare); } - sel_def = Hash_FindElement (sel_def_hash, sel_def); - if (sel_def) - return sel_def->def; - sel_def = malloc (sizeof (sel_def_t)); - sel_def->def = new_def (type_SEL.aux_type, ".imm", pr.scope); - sel_def->def->initialized = sel_def->def->constant = 1; - sel_def->def->nosave = 1; - sel_def->def->ofs = new_location (type_SEL.aux_type, pr.near_data); - EMIT_STRING (G_INT (sel_def->def->ofs), sel_id); - EMIT_STRING (G_INT (sel_def->def->ofs + 1), sel_types); - sel_def->sel_id = G_INT (sel_def->def->ofs); - sel_def->sel_types = G_INT (sel_def->def->ofs + 1); - Hash_AddElement (sel_def_hash, sel_def); - return sel_def->def; + sel = Hash_FindElement (sel_hash, sel); + if (sel) + return sel->index; + sel = malloc (sizeof (selector_t)); + sel->name = _sel.name; + sel->types = _sel.types; + sel->index = sel_index++; + Hash_AddElement (sel_hash, sel); + Hash_AddElement (sel_index_hash, sel); + return sel->index; +} + +selector_t * +get_selector (expr_t *sel) +{ + selector_t _sel = {0, 0, sel->e.pointer.val}; + _sel.index /= type_size (type_SEL.aux_type); + return (selector_t *) Hash_FindElement (sel_index_hash, &_sel); +} + +def_t * +emit_selectors (void) +{ + def_t *sel_def; + type_t *sel_type; + pr_sel_t *sel; + selector_t **selectors, **s; + + if (!sel_index) + return 0; + + sel_type = array_type (type_SEL.aux_type, sel_index); + sel_def = get_def (type_SEL.aux_type, "_OBJ_SELECTOR_TABLE", pr.scope, + st_extern); + sel_def->type = sel_type; + sel_def->ofs = new_location (sel_type, pr.near_data); + set_storage_bits (sel_def, st_static); + sel = G_POINTER (pr_sel_t, sel_def->ofs); + selectors = (selector_t **) Hash_GetList (sel_hash); + + for (s = selectors; *s; s++) { + EMIT_STRING (sel[(*s)->index].sel_id, (*s)->name); + EMIT_STRING (sel[(*s)->index].sel_types, (*s)->types); + } + free (selectors); + return sel_def; } def_t * @@ -379,8 +423,11 @@ emit_methods (methodlist_t *_methods, const char *name, int instance) void clear_selectors (void) { - if (sel_def_hash) - Hash_FlushTable (sel_def_hash); + if (sel_hash) { + Hash_FlushTable (sel_hash); + Hash_FlushTable (sel_index_hash); + } + sel_index = 0; if (known_methods) Hash_FlushTable (known_methods); } diff --git a/tools/qfprogs/source/modules.c b/tools/qfprogs/source/modules.c index 5d34340ff..23ce8bd03 100644 --- a/tools/qfprogs/source/modules.c +++ b/tools/qfprogs/source/modules.c @@ -72,6 +72,21 @@ dump_methods (progs_t *pr, pr_method_list_t *methods, int class) } } +static void +dump_selector (progs_t *pr, pr_sel_t *sel) +{ + const char *sel_name = ""; + const char *sel_types = ""; + + if (PR_StringValid (pr, sel->sel_id)) + sel_name = PR_GetString (pr, sel->sel_id); + if (PR_StringValid (pr, sel->sel_types)) + sel_types = PR_GetString (pr, sel->sel_types); + printf (" %s\n", sel_name); + if (*sel_types) + printf (" %s\n", sel_types); +} + static void dump_class (progs_t *pr, pr_class_t *class) { @@ -120,6 +135,7 @@ dump_module (progs_t *pr, pr_module_t *module) { pr_symtab_t *symtab = &G_STRUCT (pr, pr_symtab_t, module->symtab); pointer_t *ptr = symtab->defs; + pr_sel_t *sel = &G_STRUCT (pr, pr_sel_t, symtab->refs); int i; const char *module_name = ""; @@ -132,6 +148,8 @@ dump_module (progs_t *pr, pr_module_t *module) } printf (" %d %d %d\n", symtab->sel_ref_cnt, symtab->cls_def_cnt, symtab->cat_def_cnt); + for (i = 0; i < symtab->sel_ref_cnt; i++) + dump_selector (pr, sel++); for (i = 0; i < symtab->cls_def_cnt; i++) dump_class (pr, &G_STRUCT (pr, pr_class_t, *ptr++)); for (i = 0; i < symtab->cat_def_cnt; i++)