mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 20:20:43 +00:00
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:
parent
7ff9f32706
commit
385a90e8fb
13 changed files with 166 additions and 100 deletions
|
@ -350,7 +350,7 @@ typedef struct pr_va_list_s {
|
||||||
} pr_va_list_t;
|
} pr_va_list_t;
|
||||||
|
|
||||||
#define PROG_ID_VERSION 6
|
#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 {
|
typedef struct dprograms_s {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
|
|
|
@ -147,6 +147,7 @@ typedef struct pr_ivar_s pr_ivar_t;
|
||||||
|
|
||||||
typedef struct pr_symtab_s {
|
typedef struct pr_symtab_s {
|
||||||
int sel_ref_cnt;
|
int sel_ref_cnt;
|
||||||
|
pointer_t refs; // pr_sel_t
|
||||||
int cls_def_cnt;
|
int cls_def_cnt;
|
||||||
int cat_def_cnt;
|
int cat_def_cnt;
|
||||||
pointer_t defs[1]; // variable array of class pointers then
|
pointer_t defs[1]; // variable array of class pointers then
|
||||||
|
|
|
@ -194,21 +194,28 @@ pr___obj_exec_class (progs_t *pr)
|
||||||
{
|
{
|
||||||
pr_module_t *module = &P_STRUCT (pr, pr_module_t, 0);
|
pr_module_t *module = &P_STRUCT (pr, pr_module_t, 0);
|
||||||
pr_symtab_t *symtab;
|
pr_symtab_t *symtab;
|
||||||
|
pr_sel_t *sel;
|
||||||
pointer_t *ptr;
|
pointer_t *ptr;
|
||||||
int i;
|
int i;
|
||||||
//int d = developer->int_val;
|
int d = developer->int_val;
|
||||||
|
|
||||||
if (!module)
|
if (!module)
|
||||||
return;
|
return;
|
||||||
//developer->int_val = 1;
|
developer->int_val = 1;
|
||||||
symtab = &G_STRUCT (pr, pr_symtab_t, module->symtab);
|
symtab = &G_STRUCT (pr, pr_symtab_t, module->symtab);
|
||||||
if (!symtab)
|
if (!symtab)
|
||||||
return;
|
return;
|
||||||
Sys_DPrintf ("Initializing %s module with symtab @ %d : %d class%s and %d "
|
Sys_DPrintf ("Initializing %s module\n"
|
||||||
"categor%s\n",
|
"symtab @ %d : %d selector%s, %d class%s and %d categor%s\n",
|
||||||
PR_GetString (pr, module->name), module->symtab,
|
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->cls_def_cnt, symtab->cls_def_cnt == 1 ? "" : "es",
|
||||||
symtab->cat_def_cnt, symtab->cat_def_cnt == 1 ? "y" : "ies");
|
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;
|
ptr = symtab->defs;
|
||||||
for (i = 0; i < symtab->cls_def_cnt; i++) {
|
for (i = 0; i < symtab->cls_def_cnt; i++) {
|
||||||
pr_class_t *class = &G_STRUCT (pr, pr_class_t, *ptr);
|
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);
|
Hash_AddElement (pr->categories, category);
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
developer->int_val = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
|
@ -515,31 +523,6 @@ pr_sel_get_uid (progs_t *pr)
|
||||||
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
|
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
|
static void
|
||||||
pr_sel_register_name (progs_t *pr)
|
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__);
|
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
|
static void
|
||||||
pr_sel_is_mapped (progs_t *pr)
|
pr_sel_is_mapped (progs_t *pr)
|
||||||
{
|
{
|
||||||
|
@ -907,11 +881,7 @@ static struct {
|
||||||
{"sel_get_name", pr_sel_get_name},
|
{"sel_get_name", pr_sel_get_name},
|
||||||
{"sel_get_type", pr_sel_get_type},
|
{"sel_get_type", pr_sel_get_type},
|
||||||
{"sel_get_uid", pr_sel_get_uid},
|
{"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_name", pr_sel_register_name},
|
||||||
{"sel_register_typed_name", pr_sel_register_typed_name},
|
|
||||||
{"sel_is_mapped", pr_sel_is_mapped},
|
{"sel_is_mapped", pr_sel_is_mapped},
|
||||||
|
|
||||||
{"class_get_class_method", pr_class_get_class_method},
|
{"class_get_class_method", pr_class_get_class_method},
|
||||||
|
|
|
@ -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,
|
def_t *get_def (struct type_s *type, const char *name, scope_t *scope,
|
||||||
storage_class_t storage);
|
storage_class_t storage);
|
||||||
def_t *new_def (struct type_s *type, const char *name, scope_t *scope);
|
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);
|
int new_location (struct type_s *type, defspace_t *space);
|
||||||
void free_location (def_t *def);
|
void free_location (def_t *def);
|
||||||
def_t *get_tempdef (struct type_s *type, scope_t *scope);
|
def_t *get_tempdef (struct type_s *type, scope_t *scope);
|
||||||
|
|
|
@ -63,4 +63,12 @@ void emit_expr (struct expr_s *e);
|
||||||
reloc_def_def (d, POINTER_OFS (&(dest))); \
|
reloc_def_def (d, POINTER_OFS (&(dest))); \
|
||||||
} while (0)
|
} 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
|
#endif//__emit_h
|
||||||
|
|
|
@ -46,6 +46,12 @@ typedef struct method_s {
|
||||||
char *types;
|
char *types;
|
||||||
} method_t;
|
} method_t;
|
||||||
|
|
||||||
|
typedef struct selector_s {
|
||||||
|
const char *name;
|
||||||
|
const char *types;
|
||||||
|
int index;
|
||||||
|
} selector_t;
|
||||||
|
|
||||||
typedef struct methodlist_s {
|
typedef struct methodlist_s {
|
||||||
method_t *head;
|
method_t *head;
|
||||||
method_t **tail;
|
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_name (struct dstring_s *sel_id, keywordarg_t *selector);
|
||||||
void selector_types (struct dstring_s *sel_types, 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,
|
struct def_s *emit_methods (methodlist_t *methods, const char *name,
|
||||||
int instance);
|
int instance);
|
||||||
|
@ -91,4 +99,6 @@ void clear_selectors (void);
|
||||||
|
|
||||||
struct expr_s *method_check_params (method_t *method, struct expr_s *args);
|
struct expr_s *method_check_params (method_t *method, struct expr_s *args);
|
||||||
|
|
||||||
|
extern struct hashtab_s *known_methods;
|
||||||
|
|
||||||
#endif//__method_h
|
#endif//__method_h
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "QF/quakeio.h"
|
#include "QF/quakeio.h"
|
||||||
|
|
||||||
#define QFO "QFO"
|
#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 {
|
typedef struct qfo_header_s {
|
||||||
char qfo[4];
|
char qfo[4];
|
||||||
|
|
|
@ -447,8 +447,7 @@ class_find_method (class_type_t *class_type, method_t *method)
|
||||||
method_t *
|
method_t *
|
||||||
class_message_response (class_t *class, int class_msg, expr_t *sel)
|
class_message_response (class_t *class, int class_msg, expr_t *sel)
|
||||||
{
|
{
|
||||||
pr_sel_t *selector;
|
selector_t *selector;
|
||||||
char *sel_name;
|
|
||||||
method_t *m;
|
method_t *m;
|
||||||
class_t *c = class;
|
class_t *c = class;
|
||||||
category_t *cat;
|
category_t *cat;
|
||||||
|
@ -457,33 +456,32 @@ class_message_response (class_t *class, int class_msg, expr_t *sel)
|
||||||
error (sel, "not a selector");
|
error (sel, "not a selector");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
selector = &G_STRUCT (pr_sel_t, POINTER_VAL (sel->e.pointer));
|
selector = get_selector (sel);
|
||||||
sel_name = G_GETSTR (selector->sel_id);
|
|
||||||
if (class->type == &type_id) {
|
if (class->type == &type_id) {
|
||||||
m = find_method (sel_name);
|
m = find_method (selector->name);
|
||||||
if (m)
|
if (m)
|
||||||
return m;
|
return m;
|
||||||
warning (sel, "could not find method for %c%s", class_msg ? '+' : '-',
|
warning (sel, "could not find method for %c%s", class_msg ? '+' : '-',
|
||||||
sel_name);
|
selector->name);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
while (c) {
|
while (c) {
|
||||||
if (c->methods) {
|
if (c->methods) {
|
||||||
for (cat = c->categories; cat; cat = cat->next) {
|
for (cat = c->categories; cat; cat = cat->next) {
|
||||||
for (m = cat->methods->head; m; m = m->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;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (m = c->methods->head; m; m = m->next) {
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = c->super_class;
|
c = c->super_class;
|
||||||
}
|
}
|
||||||
warning (sel, "%s does not respond to %c%s", class->name,
|
warning (sel, "%s does not respond to %c%s", class->name,
|
||||||
class_msg ? '+' : '-', sel_name);
|
class_msg ? '+' : '-', selector->name);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -636,6 +634,7 @@ class_finish_module (void)
|
||||||
int num_classes = 0;
|
int num_classes = 0;
|
||||||
int num_categories = 0;
|
int num_categories = 0;
|
||||||
int i;
|
int i;
|
||||||
|
def_t *selector_table_def;
|
||||||
struct_t *symtab_type;
|
struct_t *symtab_type;
|
||||||
def_t *symtab_def;
|
def_t *symtab_def;
|
||||||
pr_symtab_t *symtab;
|
pr_symtab_t *symtab;
|
||||||
|
@ -647,6 +646,7 @@ class_finish_module (void)
|
||||||
function_t *init_func;
|
function_t *init_func;
|
||||||
expr_t *init_expr;
|
expr_t *init_expr;
|
||||||
|
|
||||||
|
selector_table_def = emit_selectors ();
|
||||||
if (class_hash) {
|
if (class_hash) {
|
||||||
classes = (class_t **) Hash_GetList (class_hash);
|
classes = (class_t **) Hash_GetList (class_hash);
|
||||||
for (cl = classes; *cl; cl++)
|
for (cl = classes; *cl; cl++)
|
||||||
|
@ -659,11 +659,12 @@ class_finish_module (void)
|
||||||
if ((*ca)->def && !(*ca)->def->external)
|
if ((*ca)->def && !(*ca)->def->external)
|
||||||
num_categories++;
|
num_categories++;
|
||||||
}
|
}
|
||||||
if (!num_classes && !num_categories)
|
if (!selector_table_def && !num_classes && !num_categories)
|
||||||
return;
|
return;
|
||||||
symtab_type = get_struct (0, 1);
|
symtab_type = get_struct (0, 1);
|
||||||
init_struct (symtab_type, new_type (), str_struct, 0);
|
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_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, "cls_def_cnt", vis_public);
|
||||||
new_struct_field (symtab_type, &type_integer, "cat_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++)
|
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->initialized = symtab_def->constant = 1;
|
||||||
symtab_def->nosave = 1;
|
symtab_def->nosave = 1;
|
||||||
symtab = &G_STRUCT (pr_symtab_t, symtab_def->ofs);
|
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->cls_def_cnt = num_classes;
|
||||||
symtab->cat_def_cnt = num_categories;
|
symtab->cat_def_cnt = num_categories;
|
||||||
def_ptr = symtab->defs;
|
def_ptr = symtab->defs;
|
||||||
|
@ -698,7 +703,7 @@ class_finish_module (void)
|
||||||
module_def->nosave = 1;
|
module_def->nosave = 1;
|
||||||
module = &G_STRUCT (pr_module_t, module_def->ofs);
|
module = &G_STRUCT (pr_module_t, module_def->ofs);
|
||||||
module->size = type_size (type_module);
|
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);
|
EMIT_DEF (module->symtab, symtab_def);
|
||||||
|
|
||||||
exec_class_def = get_def (&type_obj_exec_class, "__obj_exec_class",
|
exec_class_def = get_def (&type_obj_exec_class, "__obj_exec_class",
|
||||||
|
|
|
@ -156,7 +156,7 @@ new_scope (scope_type type, defspace_t *space, scope_t *parent)
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
set_storage_bits (def_t *def, storage_class_t storage)
|
set_storage_bits (def_t *def, storage_class_t storage)
|
||||||
{
|
{
|
||||||
switch (storage) {
|
switch (storage) {
|
||||||
|
|
|
@ -2473,16 +2473,22 @@ selector_expr (keywordarg_t *selector)
|
||||||
dstring_t *sel_id = dstring_newstr ();
|
dstring_t *sel_id = dstring_newstr ();
|
||||||
dstring_t *sel_types = dstring_newstr ();
|
dstring_t *sel_types = dstring_newstr ();
|
||||||
expr_t *sel;
|
expr_t *sel;
|
||||||
|
def_t *sel_def;
|
||||||
|
int index;
|
||||||
|
|
||||||
selector = copy_keywordargs (selector);
|
selector = copy_keywordargs (selector);
|
||||||
selector = (keywordarg_t *) reverse_params ((param_t *) selector);
|
selector = (keywordarg_t *) reverse_params ((param_t *) selector);
|
||||||
selector_name (sel_id, selector);
|
selector_name (sel_id, selector);
|
||||||
selector_types (sel_types, selector);
|
selector_types (sel_types, selector);
|
||||||
//printf ("'%s' '%s'\n", sel_id->str, sel_types->str);
|
//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_id);
|
||||||
dstring_delete (sel_types);
|
dstring_delete (sel_types);
|
||||||
return address_expr (sel, 0, 0);
|
return address_expr (sel, new_short_expr (index), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
|
|
|
@ -274,7 +274,7 @@ ReuseConstant (expr_t *expr, def_t *def)
|
||||||
break;
|
break;
|
||||||
case ex_pointer:
|
case ex_pointer:
|
||||||
if (e.e.pointer.def)
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -266,63 +266,107 @@ selector_types (dstring_t *sel_types, keywordarg_t *selector)
|
||||||
dstring_clearstr (sel_types);
|
dstring_clearstr (sel_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
static hashtab_t *sel_hash;
|
||||||
string_t sel_id;
|
static hashtab_t *sel_index_hash;
|
||||||
string_t sel_types;
|
static int sel_index;
|
||||||
def_t *def;
|
|
||||||
} sel_def_t;
|
|
||||||
|
|
||||||
static hashtab_t *sel_def_hash;
|
|
||||||
|
|
||||||
static unsigned long
|
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;
|
unsigned long hash;
|
||||||
|
|
||||||
hash = Hash_String (G_GETSTR (sel_def->sel_id))
|
hash = Hash_String (sel->name) ^ Hash_String (sel->types);
|
||||||
^ Hash_String (G_GETSTR (sel_def->sel_types));
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
selector_t *s1 = (selector_t *) _s1;
|
||||||
sel_def_t *sd2 = (sel_def_t*)_sd2;
|
selector_t *s2 = (selector_t *) _s2;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
cmp = strcmp (G_GETSTR (sd1->sel_id), G_GETSTR (sd2->sel_id)) == 0;
|
cmp = strcmp (s1->name, s2->name) == 0;
|
||||||
if (cmp)
|
if (cmp)
|
||||||
cmp = strcmp (G_GETSTR (sd1->sel_types),
|
cmp = strcmp (s1->types, s2->types) == 0;
|
||||||
G_GETSTR (sd2->sel_types)) == 0;
|
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
def_t *
|
static unsigned long
|
||||||
selector_def (const char *sel_id, const char *sel_types)
|
sel_index_get_hash (void *_sel, void *unused)
|
||||||
{
|
{
|
||||||
sel_def_t _sel_def = {ReuseString (sel_id), ReuseString (sel_types), 0};
|
selector_t *sel = (selector_t *) _sel;
|
||||||
sel_def_t *sel_def = &_sel_def;
|
return sel->index;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sel_def_hash) {
|
static int
|
||||||
sel_def_hash = Hash_NewTable (1021, 0, 0, 0);
|
sel_index_compare (void *_s1, void *_s2, void *unused)
|
||||||
Hash_SetHashCompare (sel_def_hash, sel_def_get_hash, sel_def_compare);
|
{
|
||||||
|
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);
|
sel = Hash_FindElement (sel_hash, sel);
|
||||||
if (sel_def)
|
if (sel)
|
||||||
return sel_def->def;
|
return sel->index;
|
||||||
sel_def = malloc (sizeof (sel_def_t));
|
sel = malloc (sizeof (selector_t));
|
||||||
sel_def->def = new_def (type_SEL.aux_type, ".imm", pr.scope);
|
sel->name = _sel.name;
|
||||||
sel_def->def->initialized = sel_def->def->constant = 1;
|
sel->types = _sel.types;
|
||||||
sel_def->def->nosave = 1;
|
sel->index = sel_index++;
|
||||||
sel_def->def->ofs = new_location (type_SEL.aux_type, pr.near_data);
|
Hash_AddElement (sel_hash, sel);
|
||||||
EMIT_STRING (G_INT (sel_def->def->ofs), sel_id);
|
Hash_AddElement (sel_index_hash, sel);
|
||||||
EMIT_STRING (G_INT (sel_def->def->ofs + 1), sel_types);
|
return sel->index;
|
||||||
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);
|
selector_t *
|
||||||
return sel_def->def;
|
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 *
|
def_t *
|
||||||
|
@ -379,8 +423,11 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
|
||||||
void
|
void
|
||||||
clear_selectors (void)
|
clear_selectors (void)
|
||||||
{
|
{
|
||||||
if (sel_def_hash)
|
if (sel_hash) {
|
||||||
Hash_FlushTable (sel_def_hash);
|
Hash_FlushTable (sel_hash);
|
||||||
|
Hash_FlushTable (sel_index_hash);
|
||||||
|
}
|
||||||
|
sel_index = 0;
|
||||||
if (known_methods)
|
if (known_methods)
|
||||||
Hash_FlushTable (known_methods);
|
Hash_FlushTable (known_methods);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
static void
|
||||||
dump_class (progs_t *pr, pr_class_t *class)
|
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);
|
pr_symtab_t *symtab = &G_STRUCT (pr, pr_symtab_t, module->symtab);
|
||||||
pointer_t *ptr = symtab->defs;
|
pointer_t *ptr = symtab->defs;
|
||||||
|
pr_sel_t *sel = &G_STRUCT (pr, pr_sel_t, symtab->refs);
|
||||||
int i;
|
int i;
|
||||||
const char *module_name = "<invalid string>";
|
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,
|
printf (" %d %d %d\n", symtab->sel_ref_cnt, symtab->cls_def_cnt,
|
||||||
symtab->cat_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++)
|
for (i = 0; i < symtab->cls_def_cnt; i++)
|
||||||
dump_class (pr, &G_STRUCT (pr, pr_class_t, *ptr++));
|
dump_class (pr, &G_STRUCT (pr, pr_class_t, *ptr++));
|
||||||
for (i = 0; i < symtab->cat_def_cnt; i++)
|
for (i = 0; i < symtab->cat_def_cnt; i++)
|
||||||
|
|
Loading…
Reference in a new issue