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.
This commit is contained in:
Bill Currie 2003-08-23 06:15:19 +00:00
parent 7ff9f32706
commit 385a90e8fb
13 changed files with 166 additions and 100 deletions

View file

@ -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;

View file

@ -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

View file

@ -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},

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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];

View file

@ -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",

View file

@ -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) {

View file

@ -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 *

View file

@ -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;

View file

@ -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);
}

View file

@ -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 = "<invalid string>";
const char *sel_types = "<invalid string>";
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 = "<invalid string>";
@ -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++)