make sel_get_uid and class_get_instance_method work

This commit is contained in:
Bill Currie 2003-08-23 22:16:42 +00:00
parent edb716ada0
commit b50d283b28
3 changed files with 67 additions and 25 deletions

View file

@ -364,6 +364,7 @@ struct progs_s {
struct hashtab_s *resource_hash;
// obj info
struct hashtab_s *selectors;
struct hashtab_s *classes;
struct hashtab_s *categories;
struct hashtab_s *protocols;

View file

@ -68,6 +68,12 @@ call_function (progs_t *pr, func_t func)
}
}
static const char *
selector_get_key (void *s, void *pr)
{
return PR_GetString ((progs_t *)pr, ((pr_sel_t *)s)->sel_id);
}
static const char *
class_get_key (void *c, void *pr)
{
@ -214,6 +220,7 @@ pr___obj_exec_class (progs_t *pr)
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;
@ -256,7 +263,7 @@ pr___obj_exec_class (progs_t *pr)
//====================================================================
static func_t
static pr_method_t *
obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
{
pr_class_t *c = class;
@ -270,7 +277,7 @@ obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
for (i = 0, method = method_list->method_list;
i < method_list->method_count; i++, method++) {
if (method->method_name.sel_id == selector->sel_id)
return method->method_imp;
return method;
}
method_list = &G_STRUCT (pr, pr_method_list_t,
method_list->method_next);
@ -280,7 +287,7 @@ obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
return 0;
}
static func_t
static pr_method_t *
obj_msg_lookup (progs_t *pr, pr_id_t *receiver, pr_sel_t *op)
{
pr_class_t *class;
@ -290,7 +297,7 @@ obj_msg_lookup (progs_t *pr, pr_id_t *receiver, pr_sel_t *op)
return obj_find_message (pr, class, op);
}
static func_t
static pr_method_t *
obj_msg_lookup_super (progs_t *pr, pr_super_t *super, pr_sel_t *op)
{
pr_class_t *class;
@ -337,7 +344,8 @@ pr_obj_msg_lookup (progs_t *pr)
{
pr_id_t *receiver = &P_STRUCT (pr, pr_id_t, 0);
pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1);
R_INT (pr) = obj_msg_lookup (pr, receiver, op);
pr_method_t *method = obj_msg_lookup (pr, receiver, op);
R_INT (pr) = method ? method->method_imp : 0;
}
static void
@ -345,8 +353,8 @@ pr_obj_msg_lookup_super (progs_t *pr)
{
pr_super_t *super = &P_STRUCT (pr, pr_super_t, 0);
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
R_INT (pr) = obj_msg_lookup_super (pr, super, _cmd);
pr_method_t *method = obj_msg_lookup_super (pr, super, _cmd);
R_INT (pr) = method ? method->method_imp : 0;
}
static void
@ -355,9 +363,9 @@ pr_obj_msg_sendv (progs_t *pr)
pr_id_t *receiver = &P_STRUCT (pr, pr_id_t, 0);
pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1);
pr_va_list_t args = P_STRUCT (pr, pr_va_list_t, 2);
func_t imp = obj_msg_lookup (pr, receiver, op);
pr_method_t *method = obj_msg_lookup (pr, receiver, op);
if (!imp)
if (!method)
PR_RunError (pr, "%s does not respond to %s",
PR_GetString (pr, object_get_class_name (pr, receiver)),
PR_GetString (pr, op->sel_id));
@ -365,7 +373,7 @@ pr_obj_msg_sendv (progs_t *pr)
args.count = 6;
memcpy (P_GPOINTER (pr, 2), G_GPOINTER (pr, args.list),
args.count * 4 * pr->pr_param_size);
call_function (pr, imp);
call_function (pr, method->method_imp);
}
static void
@ -435,7 +443,7 @@ pr_obj_msgSend (progs_t *pr)
{
pr_id_t *self = &P_STRUCT (pr, pr_id_t, 0);
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
func_t imp;
pr_method_t *method;
if (!self) {
R_INT (pr) = R_INT (pr);
@ -443,13 +451,13 @@ pr_obj_msgSend (progs_t *pr)
}
if (!_cmd)
PR_RunError (pr, "null selector");
imp = obj_msg_lookup (pr, self, _cmd);
if (!imp)
method = obj_msg_lookup (pr, self, _cmd);
if (!method)
PR_RunError (pr, "%s does not respond to %s",
PR_GetString (pr, object_get_class_name (pr, self)),
PR_GetString (pr, _cmd->sel_id));
call_function (pr, imp);
call_function (pr, method->method_imp);
}
static void
@ -457,17 +465,17 @@ pr_obj_msgSend_super (progs_t *pr)
{
pr_super_t *super = &P_STRUCT (pr, pr_super_t, 0);
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
func_t imp;
pr_method_t *method;
imp = obj_msg_lookup_super (pr, super, _cmd);
if (!imp) {
method = obj_msg_lookup_super (pr, super, _cmd);
if (!method) {
pr_id_t *self = &G_STRUCT (pr, pr_id_t, super->self);
PR_RunError (pr, "%s does not respond to %s",
PR_GetString (pr, object_get_class_name (pr, self)),
PR_GetString (pr, _cmd->sel_id));
}
P_POINTER (pr, 0) = super->self;
call_function (pr, imp);
call_function (pr, method->method_imp);
}
static void
@ -518,9 +526,9 @@ pr_sel_get_type (progs_t *pr)
static void
pr_sel_get_uid (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);
pr_sel_t *sel = Hash_Find (pr->selectors, name);
RETURN_POINTER (pr, sel);
}
static void
@ -553,10 +561,10 @@ pr_class_get_class_method (progs_t *pr)
static void
pr_class_get_instance_method (progs_t *pr)
{
//pr_class_t *class = &P_STRUCT (pr, pr_class_t, 0);
//pr_sel_t *aSel = &P_STRUCT (pr, pr_sel_t, 1);
//XXX
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
pr_class_t *class = &P_STRUCT (pr, pr_class_t, 0);
pr_sel_t *aSel = &P_STRUCT (pr, pr_sel_t, 1);
pr_method_t *method = obj_find_message (pr, class, aSel);
RETURN_POINTER (pr, method);
}
static void
@ -934,6 +942,11 @@ PR_InitRuntime (progs_t *pr)
pr_class_t **class_list, **class;
pr_category_t **category_list, **category;
if (!pr->selectors)
pr->selectors = Hash_NewTable (1021, selector_get_key, 0, pr);
else
Hash_FlushTable (pr->selectors);
if (!pr->classes)
pr->classes = Hash_NewTable (1021, class_get_key, 0, pr);
else

View file

@ -1,11 +1,39 @@
integer (integer argc, string []argv) main =
{
local integer i;
local SEL sel;
for (i = 0; i < argc; i++) {
print (argv[i]);
print ("\n");
}
local id foo = [[Foo alloc] init];
[foo run];
sel = sel_get_uid ("run");
if (sel) {
print ("found selector for `run'\n");
if ([foo respondsToSelector:sel])
print ("foo responds to `run'\n");
else
print ("foo does not repond to `run'\n");
} else
print ("did not find selector for `run'\n");
sel = sel_get_uid ("alloc");
if (sel) {
print ("found selector for `alloc'\n");
if ([Object instancesRespondToSelector:sel])
print ("Object instances respond to `alloc'\n");
else
print ("Object instances do not repond to `alloc'\n");
} else
print ("did not find selector for `alloc'\n");
sel = sel_get_uid ("run:with:me:");
if (sel) {
print ("found selector for `run:with:me:'\n");
if ([Object instancesRespondToSelector:sel])
print ("Object instances respond to `run:with:me:'\n");
else
print ("Object instances do not repond to `run:with:me:'\n");
} else
print ("did not find selector for `run:with:me:'\n");
return 0;
};