do proper selector registration. unfortunatly, I discovered I'd created pr_method_t incorrectly and so had to bump the progs version again

This is an imperfect revision of history.
This commit is contained in:
Bill Currie 2004-11-10 05:37:00 +00:00 committed by Jeff Teunissen
parent 6ad13faf98
commit b35561504c
9 changed files with 378 additions and 135 deletions

View file

@ -370,7 +370,7 @@ typedef struct pr_va_list_s {
} pr_va_list_t;
#define PROG_ID_VERSION 6
#define PROG_VERSION 0x00fff004 // MMmmmRRR 0.fff.004 (hex)
#define PROG_VERSION 0x00fff005 // MMmmmRRR 0.fff.005 (hex)
typedef struct dprograms_s {
unsigned int version;

View file

@ -128,7 +128,7 @@ typedef struct pr_method_list_s {
pointer_t method_next;
int method_count;
struct pr_method_s {
pr_sel_t method_name;
pointer_t method_name; // pr_sel_t
string_t method_types;
func_t method_imp; // typedef id (id, SEL, ...) IMP
} method_list[1];

View file

@ -1220,13 +1220,17 @@ struct progs_s {
pr_resource_t *resources;
struct hashtab_s *resource_hash;
// obj info
struct hashtab_s *selectors;
/// obj info
//@{
int selector_index;
int selector_index_max;
void *selector_sels;
string_t *selector_names;
struct hashtab_s *selector_hash;
struct hashtab_s *classes;
struct hashtab_s *categories;
struct hashtab_s *protocols;
// debug info
//@}
/// debug info
//@{

View file

@ -59,9 +59,10 @@ static void
}
static const char *
selector_get_key (void *s, void *pr)
selector_get_key (void *s, void *_pr)
{
return PR_GetString ((progs_t *)pr, ((pr_sel_t *)s)->sel_id);
progs_t *pr = (progs_t *) _pr;
return PR_GetString (pr, pr->selector_names[(int) s]);
}
static const char *
@ -94,22 +95,12 @@ category_compare (void *_c1, void *_c2, void *_pr)
return strcmp (cat1, cat2) == 0 && strcmp (cls1, cls2) == 0;
}
static void
dump_ivars (progs_t *pr, pointer_t _ivars)
static inline int
sel_eq (pr_sel_t *s1, pr_sel_t *s2)
{
pr_ivar_list_t *ivars;
int i;
if (!_ivars)
return;
ivars = &G_STRUCT (pr, pr_ivar_list_t, _ivars);
for (i = 0; i < ivars->ivar_count; i++) {
Sys_Printf (" %s %s %d\n",
PR_GetString (pr, ivars->ivar_list[i].ivar_name),
PR_GetString (pr, ivars->ivar_list[i].ivar_type),
ivars->ivar_list[i].ivar_offset);
}
if (!s1 || !s2)
return s1 == s2;
return s1->sel_id == s2->sel_id;
}
static int
@ -171,99 +162,270 @@ finish_class (progs_t *pr, pr_class_t *class, pointer_t object_ptr)
class->super_class);
}
static void
finish_category (progs_t *pr, pr_category_t *category)
{
const char *class_name = PR_GetString (pr, category->class_name);
const char *category_name = PR_GetString (pr, category->category_name);
pr_class_t *class = Hash_Find (pr->classes, class_name);
pr_method_list_t *method_list;
//====================================================================
static int
add_sel_name (progs_t *pr, const char *name)
{
int ind = ++pr->selector_index;
int size, i;
if (pr->selector_index > pr->selector_index_max) {
size = pr->selector_index_max + 128;
pr->selector_sels = realloc (pr->selector_sels,
size * sizeof (obj_list *));
pr->selector_names = realloc (pr->selector_names,
size * sizeof (string_t));
for (i = pr->selector_index_max; i < size; i++) {
((obj_list **) pr->selector_sels)[i] = 0;
pr->selector_names[i] = 0;
}
pr->selector_index_max = size;
}
pr->selector_names[ind] = PR_SetString (pr, name);
return ind;
}
static pr_sel_t *
sel_register_typed_name (progs_t *pr, const char *name, const char *types,
pr_sel_t *sel)
{
int index;
int is_new = 0;
obj_list *l;
index = (int) Hash_Find (pr->selector_hash, name);
if (index) {
for (l = ((obj_list **) pr->selector_sels)[index]; l; l = l->next) {
pr_sel_t *s = l->data;
if (!types || !s->sel_types) {
if (!s->sel_types && !types) {
if (sel) {
sel->sel_id = index;
return sel;
}
return s;
}
} else if (strcmp (PR_GetString (pr, s->sel_types), types) == 0) {
if (sel) {
sel->sel_id = index;
return sel;
}
return s;
}
}
} else {
index = add_sel_name (pr, name);
is_new = 1;
}
if (!sel)
sel = PR_Zone_Malloc (pr, sizeof (pr_sel_t));
sel->sel_id = index;
sel->sel_types = PR_SetString (pr, types);
l = obj_list_new ();
l->data = sel;
l->next = ((obj_list **) pr->selector_sels)[index];
((obj_list **) pr->selector_sels)[index] = l;
if (is_new)
Hash_Add (pr->selector_hash, (void *)index);
return sel;
}
static pr_sel_t *
sel_register_name (progs_t *pr, const char *name)
{
return sel_register_typed_name (pr, name, 0, 0);
}
static void
register_selectors_from_list (progs_t *pr, pr_method_list_t *method_list)
{
int i;
for (i = 0; i < method_list->method_count; i++) {
pr_method_t *method = &method_list->method_list[i];
const char *name = PR_GetString (pr, method->method_name);
const char *types = PR_GetString (pr, method->method_types);
pr_sel_t *sel = sel_register_typed_name (pr, name, types, 0);
method->method_name = PR_SetPointer (pr, sel);
}
}
static void
obj_register_selectors_from_class (progs_t *pr, pr_class_t *class)
{
pr_method_list_t *method_list = &G_STRUCT (pr, pr_method_list_t,
class->methods);
while (method_list) {
register_selectors_from_list (pr, method_list);
method_list = &G_STRUCT (pr, pr_method_list_t,
method_list->method_next);
}
}
static void
obj_init_protocols (progs_t *pr, pr_protocol_list_t *protos)
{
pr_class_t *proto_class;
pr_protocol_t *proto;
int i;
if (!protos)
return;
if (!(proto_class = Hash_Find (pr->classes, "Protocol"))) {
pr->unclaimed_proto_list = list_cons (protos,
pr->unclaimed_proto_list);
return;
}
for (i = 0; i < protos->count; i++) {
proto = &G_STRUCT (pr, pr_protocol_t, protos->list[i]);
if (!proto->class_pointer) {
proto->class_pointer = PR_SetPointer (pr, proto_class);
obj_init_protocols (pr, &G_STRUCT (pr, pr_protocol_list_t,
proto->protocol_list));
} else {
PR_RunError (pr, "protocol broken");
}
}
}
static void
class_add_method_list (progs_t *pr, pr_class_t *class, pr_method_list_t *list)
{
int i;
for (i = 0; i < list->method_count; i++) {
pr_method_t *method = &list->method_list[i];
if (method->method_name) {
const char *name = PR_GetString (pr, method->method_name);
const char *types = PR_GetString (pr, method->method_types);
pr_sel_t *sel = sel_register_typed_name (pr, name, types, 0);
method->method_name = PR_SetPointer (pr, sel);
}
}
list->method_next = class->methods;
class->methods = PR_SetPointer (pr, list);
}
static void
obj_class_add_protocols (progs_t *pr, pr_class_t *class,
pr_protocol_list_t *protos)
{
if (!protos)
return;
protos->next = class->protocols;
class->protocols = protos->next;
}
static void
finish_category (progs_t *pr, pr_category_t *category, pr_class_t *class)
{
pr_method_list_t *method_list;
pr_protocol_list_t *protocol_list;
if (!class)
PR_Error (pr, "broken category %s (%s): class %s not found",
class_name, category_name, class_name);
if (category->instance_methods) {
method_list = &G_STRUCT (pr, pr_method_list_t,
category->instance_methods);
method_list->method_next = class->methods;
class->methods = category->instance_methods;
class_add_method_list (pr, class, method_list);
}
if (category->class_methods) {
pr_class_t *meta = &G_STRUCT (pr, pr_class_t, class->class_pointer);
method_list = &G_STRUCT (pr, pr_method_list_t,
category->class_methods);
method_list->method_next = meta->methods;
meta->methods = category->class_methods;
class_add_method_list (pr, meta, method_list);
}
if (category->protocols) {
protocol_list = &G_STRUCT (pr, pr_protocol_list_t,
category->protocols);
obj_init_protocols (pr, protocol_list);
obj_class_add_protocols (pr, class, protocol_list);
}
}
static void
rua___obj_exec_class (progs_t *pr)
obj_send_message_in_list (progs_t *pr, pr_method_list_t *method_list,
pr_class_t *class, pr_sel_t *op)
{
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;
if (!module)
if (!method_list)
return;
//developer->int_val = 1;
symtab = &G_STRUCT (pr, pr_symtab_t, module->symtab);
if (!symtab)
return;
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));
Hash_Add (pr->selectors, sel);
sel++;
}
ptr = symtab->defs;
for (i = 0; i < symtab->cls_def_cnt; i++) {
pr_class_t *class = &G_STRUCT (pr, pr_class_t, *ptr);
pr_class_t *meta = &G_STRUCT (pr, pr_class_t, class->class_pointer);
Sys_DPrintf ("Class %s @ %d\n", PR_GetString (pr, class->name), *ptr);
Sys_DPrintf (" class pointer: %d\n", class->class_pointer);
Sys_DPrintf (" super class: %s\n",
PR_GetString (pr, class->super_class));
Sys_DPrintf (" instance variables: %d @ %d\n", class->instance_size,
class->ivars);
if (developer->int_val)
dump_ivars (pr, class->ivars);
Sys_DPrintf (" instance methods: %d\n", class->methods);
Sys_DPrintf (" protocols: %d\n", class->protocols);
Sys_DPrintf (" class methods: %d\n", meta->methods);
Sys_DPrintf (" instance variables: %d @ %d\n", meta->instance_size,
meta->ivars);
if (developer->int_val)
dump_ivars (pr, meta->ivars);
obj_send_message_in_list (pr, &G_STRUCT (pr, pr_method_list_t,
method_list->method_next),
class, op);
Hash_Add (pr->classes, class);
ptr++;
for (i = 0; i < method_list->method_count; i++) {
pr_method_t *mth = &method_list->method_list[i];
if (mth->method_name && sel_eq (&G_STRUCT (pr, pr_sel_t,
mth->method_name), op)
&& !Hash_FindElement (pr->load_methods, (void *)mth->method_imp)) {
Hash_AddElement (pr->load_methods, (void *)mth->method_imp);
PR_ExecuteProgram (pr, mth->method_imp);
break;
}
}
for (i = 0; i < symtab->cat_def_cnt; i++) {
pr_category_t *category = &G_STRUCT (pr, pr_category_t, *ptr);
Sys_DPrintf ("Category %s (%s) @ %d\n",
PR_GetString (pr, category->class_name),
PR_GetString (pr, category->category_name), *ptr);
Sys_DPrintf (" instance methods: %d\n", category->instance_methods);
Sys_DPrintf (" class methods: %d\n", category->class_methods);
Sys_DPrintf (" protocols: %d\n", category->protocols);
Hash_AddElement (pr->categories, category);
ptr++;
}
//developer->int_val = d;
}
//====================================================================
static void
send_load (progs_t *pr, class_tree *tree, int level)
{
pr_sel_t *load_sel = sel_register_name (pr, "load");
pr_class_t *class = tree->class;
pr_class_t *meta = &G_STRUCT (pr, pr_class_t, class->class_pointer);
pr_method_list_t *method_list = &G_STRUCT (pr, pr_method_list_t,
meta->methods);
obj_send_message_in_list (pr, method_list, class, load_sel);
}
static void
obj_send_load (progs_t *pr)
{
obj_list *m;
if (pr->unresolved_classes) {
pr_class_t *class = ((obj_list *) pr->unresolved_classes)->data;
const char *super_class = PR_GetString (pr, class->super_class);
while (Hash_Find (pr->classes, super_class)) {
list_remove ((obj_list **) &pr->unresolved_classes);
if (pr->unresolved_classes) {
class = ((obj_list *) pr->unresolved_classes)->data;
super_class = PR_GetString (pr, class->super_class);
} else {
break;
}
}
if (pr->unresolved_classes)
return;
}
//XXX constant string stuff here (see init.c in libobjc source)
for (m = pr->module_list; m; m = m->next)
obj_create_classes_tree (pr, m->data);
while (pr->class_tree_list) {
obj_preorder_traverse (pr, ((obj_list *) pr->class_tree_list)->data,
0, send_load);
obj_postorder_traverse (pr, ((obj_list *) pr->class_tree_list)->data,
0, obj_destroy_class_tree_node);
list_remove ((obj_list **) &pr->class_tree_list);
}
//XXX callback
//for (m = pr->module_list; m; m = m->next)
// obj_create_classes_tree (pr, m->data);
obj_list_free (pr->module_list);
pr->module_list = 0;
}
static pr_method_t *
obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
@ -271,6 +433,7 @@ obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
pr_class_t *c = class;
pr_method_list_t *method_list;
pr_method_t *method;
pr_sel_t *sel;
int i;
while (c) {
@ -278,7 +441,8 @@ obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
while (method_list) {
for (i = 0, method = method_list->method_list;
i < method_list->method_count; i++, method++) {
if (method->method_name.sel_id == selector->sel_id)
sel = &G_STRUCT (pr, pr_sel_t, method->method_name);
if (sel->sel_id == selector->sel_id)
return method;
}
method_list = &G_STRUCT (pr, pr_method_list_t,
@ -579,13 +743,18 @@ static void
rua_sel_get_name (progs_t *pr)
{
pr_sel_t *sel = &P_STRUCT (pr, pr_sel_t, 0);
R_INT (pr) = sel->sel_id;
if (sel->sel_id > 0 && sel->sel_id <= pr->selector_index)
R_STRING (pr) = pr->selector_names[sel->sel_id];
else
R_STRING (pr) = 0;
}
static void
rua_sel_get_type (progs_t *pr)
{
pr_sel_t *sel = &P_STRUCT (pr, pr_sel_t, 0);
R_INT (pr) = sel->sel_types;
}
@ -593,24 +762,24 @@ static void
rua_sel_get_uid (progs_t *pr)
{
const char *name = P_GSTRING (pr, 0);
pr_sel_t *sel = Hash_Find (pr->selectors, name);
RETURN_POINTER (pr, sel);
RETURN_POINTER (pr, sel_register_typed_name (pr, name, 0, 0));
}
static void
rua_sel_register_name (progs_t *pr)
{
//const char *name = P_GSTRING (pr, 0);
//XXX
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
const char *name = P_GSTRING (pr, 0);
RETURN_POINTER (pr, sel_register_typed_name (pr, name, 0, 0));
}
static void
rua_sel_is_mapped (progs_t *pr)
{
//pr_sel_t *sel = &P_STRUCT (pr, pr_sel_t, 0);
//XXX
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
// FIXME might correspond to a string
pr_sel_t *sel = &P_STRUCT (pr, pr_sel_t, 0);
R_INT (pr) = sel->sel_id > 0 && sel->sel_id <= pr->selector_index;
}
//====================================================================
@ -1049,10 +1218,19 @@ rua_init_finish (progs_t *pr)
static int
rua_init_runtime (progs_t *pr)
{
if (!pr->selectors)
pr->selectors = Hash_NewTable (1021, selector_get_key, 0, pr);
ddef_t *def;
int i;
if (!pr->selector_hash)
pr->selector_hash = Hash_NewTable (1021, selector_get_key, 0, pr);
else
Hash_FlushTable (pr->selectors);
Hash_FlushTable (pr->selector_hash);
pr->selector_index = 0;
for (i = 0; i < pr->selector_index_max; i++) {
obj_list_free (((obj_list **) pr->selector_sels)[i]);
((obj_list **) pr->selector_sels)[i] = 0;
pr->selector_names[i] = 0;
}
if (!pr->classes)
pr->classes = Hash_NewTable (1021, class_get_key, 0, pr);

View file

@ -88,13 +88,15 @@ struct expr_s *send_message (int super);
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);
int selector_index (const char *sel_id, const char *sel_types);
void method_types (struct dstring_s *sel_types, method_t *method);
int selector_index (const char *sel_id);
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);
struct def_s *emit_method_descriptions (methodlist_t *_methods,
const char *name, int instance);
void clear_selectors (void);

View file

@ -76,6 +76,7 @@ extern type_t type_IMP;
extern type_t type_supermsg;
extern type_t type_obj_exec_class;
extern type_t type_Method;
extern type_t type_method_description;
extern type_t *type_category;
extern type_t *type_ivar;
extern type_t *type_module;
@ -97,7 +98,8 @@ type_t *field_type (type_t *aux);
type_t *pointer_type (type_t *aux);
type_t *array_type (type_t *aux, int size);
void print_type (type_t *type);
void encode_type (struct dstring_s *encodking, type_t *type);
const char *encode_params (type_t *type);
void encode_type (struct dstring_s *encoding, type_t *type);
type_t *parse_type (const char *str);
int type_assignable (type_t *dst, type_t *src);
int type_size (type_t *type);

View file

@ -2564,7 +2564,6 @@ expr_t *
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;
@ -2572,15 +2571,12 @@ selector_expr (keywordarg_t *selector)
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);
index = selector_index (sel_id->str, sel_types->str);
index = selector_index (sel_id->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, new_short_expr (index), 0);
}

View file

@ -100,7 +100,7 @@ new_method (type_t *ret_type, param_t *selector, param_t *opt_parms)
meth->type = parse_params (ret_type, meth->params);
selector_name (name, (keywordarg_t *)selector);
selector_types (types, (keywordarg_t *)selector);
method_types (types, meth);
meth->name = name->str;
meth->types = types->str;
free (name);
@ -126,7 +126,7 @@ copy_method (method_t *method)
meth->instance = method->instance;
meth->selector = self->next->next;
meth->params = self;
meth->type = parse_params (method->type->aux_type, meth->params);
meth->type = method->type;
meth->name = method->name;
meth->types = method->types;
return meth;
@ -276,9 +276,10 @@ selector_name (dstring_t *sel_id, keywordarg_t *selector)
}
void
selector_types (dstring_t *sel_types, keywordarg_t *selector)
method_types (dstring_t *sel_types, method_t *method)
{
dstring_clearstr (sel_types);
encode_type (sel_types, method->type);
}
static hashtab_t *sel_hash;
@ -291,7 +292,7 @@ sel_get_hash (void *_sel, void *unused)
selector_t *sel = (selector_t *) _sel;
unsigned long hash;
hash = Hash_String (sel->name) ^ Hash_String (sel->types);
hash = Hash_String (sel->name);
return hash;
}
@ -303,8 +304,6 @@ sel_compare (void *_s1, void *_s2, void *unused)
int cmp;
cmp = strcmp (s1->name, s2->name) == 0;
if (cmp)
cmp = strcmp (s1->types, s2->types) == 0;
return cmp;
}
@ -324,9 +323,9 @@ sel_index_compare (void *_s1, void *_s2, void *unused)
}
int
selector_index (const char *sel_id, const char *sel_types)
selector_index (const char *sel_id)
{
selector_t _sel = {save_string (sel_id), save_string (sel_types), 0};
selector_t _sel = {save_string (sel_id), 0, 0};
selector_t *sel = &_sel;
if (!sel_hash) {
@ -422,8 +421,7 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
for (i = 0, method = _methods->head; method; method = method->next) {
if (!method->instance != !instance || !method->def)
continue;
EMIT_STRING (methods->method_list[i].method_name.sel_id, method->name);
EMIT_STRING (methods->method_list[i].method_name.sel_types, method->types);
EMIT_STRING (methods->method_list[i].method_name, method->name);
EMIT_STRING (methods->method_list[i].method_types, method->types);
methods->method_list[i].method_imp = G_FUNCTION (method->def->ofs);
if (method->func) {
@ -435,6 +433,48 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
return methods_def;
}
def_t *
emit_method_descriptions (methodlist_t *_methods, const char *name,
int instance)
{
const char *type = instance ? "PROTOCOL_INSTANCE" : "PROTOCOL_CLASS";
method_t *method;
int i, count;
def_t *methods_def;
pr_method_description_list_t *methods;
struct_t *method_list;
if (!_methods)
return 0;
for (count = 0, method = _methods->head; method; method = method->next)
if (!method->instance == !instance)
count++;
if (!count)
return 0;
method_list = get_struct (0, 1);
init_struct (method_list, new_type (), str_struct, 0);
new_struct_field (method_list, &type_integer, "count", vis_public);
for (i = 0; i < count; i++)
new_struct_field (method_list, &type_method_description, 0,
vis_public);
methods_def = get_def (method_list->type,
va ("_OBJ_%s_METHODS_%s", type, name),
pr.scope, st_static);
methods_def->initialized = methods_def->constant = 1;
methods_def->nosave = 1;
methods = &G_STRUCT (pr_method_description_list_t, methods_def->ofs);
methods->count = count;
for (i = 0, method = _methods->head; method; method = method->next) {
if (!method->instance != !instance || !method->def)
continue;
EMIT_STRING (methods->list[i].name, method->name);
EMIT_STRING (methods->list[i].types, method->types);
i++;
}
return methods_def;
}
void
clear_selectors (void)
{

View file

@ -85,6 +85,7 @@ type_t type_supermsg = { ev_func, ".supermsg", NULL, &type_id, -3,
type_t type_obj_exec_class = { ev_func, "function", NULL, &type_void, 1, { 0 }};
type_t type_Method = { ev_pointer, "Method" };
type_t type_Super = { ev_pointer, "Super" };
type_t type_method_description = { ev_struct, "obj_method_description" };
type_t *type_category;
type_t *type_ivar;
type_t *type_module;
@ -280,13 +281,35 @@ print_type (type_t *type)
}
}
const char *
encode_params (type_t *type)
{
const char *ret;
dstring_t *encoding = dstring_newstr ();
int i, count;
if (type->num_parms < 0)
count = -type->num_parms - 1;
else
count = type->num_parms;
for (i = 0; i < count; i++)
encode_type (encoding, type->parm_types[i]);
if (type->num_parms < 0)
dstring_appendstr (encoding, ".");
ret = save_string (encoding->str);
dstring_delete (encoding);
return ret;
}
static void
_encode_type (dstring_t *encoding, type_t *type, int level)
{
struct_field_t *field;
int i, count;
struct_t *strct;
if (!type)
return;
switch (type->type) {
case ev_void:
dstring_appendstr (encoding, "v");
@ -310,14 +333,7 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
case ev_func:
dstring_appendstr (encoding, "(");
_encode_type (encoding, type->aux_type, level + 1);
if (type->num_parms < 0)
count = -type->num_parms - 1;
else
count = type->num_parms;
for (i = 0; i < count; i++)
_encode_type (encoding, type->parm_types[i], level + 1);
if (type->num_parms < 0)
dstring_appendstr (encoding, ".");
dstring_appendstr (encoding, encode_params (type));
dstring_appendstr (encoding, ")");
break;
case ev_pointer:
@ -669,7 +685,7 @@ init_types (void)
strct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, type_SEL.aux_type, "method_name", vis_public);
new_struct_field (strct, &type_SEL, "method_name", vis_public);
new_struct_field (strct, &type_string, "method_types", vis_public);
new_struct_field (strct, &type_IMP, "method_imp", vis_public);
type_Method.aux_type = strct->type;
@ -714,6 +730,11 @@ init_types (void)
type_id.aux_type = strct->type;
class_id.ivars = strct;
strct = get_struct (0, 1);
init_struct (strct, &type_method_description, str_struct, 0);
new_struct_field (strct, &type_string, "name", vis_public);
new_struct_field (strct, &type_string, "types", vis_public);
strct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_string, "category_name", vis_public);