mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 20:20:43 +00:00
make sel_get_uid and class_get_instance_method work
This commit is contained in:
parent
edb716ada0
commit
b50d283b28
3 changed files with 67 additions and 25 deletions
|
@ -364,6 +364,7 @@ struct progs_s {
|
||||||
struct hashtab_s *resource_hash;
|
struct hashtab_s *resource_hash;
|
||||||
|
|
||||||
// obj info
|
// obj info
|
||||||
|
struct hashtab_s *selectors;
|
||||||
struct hashtab_s *classes;
|
struct hashtab_s *classes;
|
||||||
struct hashtab_s *categories;
|
struct hashtab_s *categories;
|
||||||
struct hashtab_s *protocols;
|
struct hashtab_s *protocols;
|
||||||
|
|
|
@ -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 *
|
static const char *
|
||||||
class_get_key (void *c, void *pr)
|
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);
|
sel = &G_STRUCT (pr, pr_sel_t, symtab->refs);
|
||||||
for (i = 0; i < symtab->sel_ref_cnt; i++) {
|
for (i = 0; i < symtab->sel_ref_cnt; i++) {
|
||||||
Sys_DPrintf (" %s\n", PR_GetString (pr, sel->sel_id));
|
Sys_DPrintf (" %s\n", PR_GetString (pr, sel->sel_id));
|
||||||
|
Hash_Add (pr->selectors, sel);
|
||||||
sel++;
|
sel++;
|
||||||
}
|
}
|
||||||
ptr = symtab->defs;
|
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)
|
obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
|
||||||
{
|
{
|
||||||
pr_class_t *c = class;
|
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;
|
for (i = 0, method = method_list->method_list;
|
||||||
i < method_list->method_count; i++, method++) {
|
i < method_list->method_count; i++, method++) {
|
||||||
if (method->method_name.sel_id == selector->sel_id)
|
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 = &G_STRUCT (pr, pr_method_list_t,
|
||||||
method_list->method_next);
|
method_list->method_next);
|
||||||
|
@ -280,7 +287,7 @@ obj_find_message (progs_t *pr, pr_class_t *class, pr_sel_t *selector)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static func_t
|
static pr_method_t *
|
||||||
obj_msg_lookup (progs_t *pr, pr_id_t *receiver, pr_sel_t *op)
|
obj_msg_lookup (progs_t *pr, pr_id_t *receiver, pr_sel_t *op)
|
||||||
{
|
{
|
||||||
pr_class_t *class;
|
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);
|
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)
|
obj_msg_lookup_super (progs_t *pr, pr_super_t *super, pr_sel_t *op)
|
||||||
{
|
{
|
||||||
pr_class_t *class;
|
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_id_t *receiver = &P_STRUCT (pr, pr_id_t, 0);
|
||||||
pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1);
|
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
|
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_super_t *super = &P_STRUCT (pr, pr_super_t, 0);
|
||||||
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
|
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
|
||||||
|
pr_method_t *method = obj_msg_lookup_super (pr, super, _cmd);
|
||||||
R_INT (pr) = obj_msg_lookup_super (pr, super, _cmd);
|
R_INT (pr) = method ? method->method_imp : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_id_t *receiver = &P_STRUCT (pr, pr_id_t, 0);
|
||||||
pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1);
|
pr_sel_t *op = &P_STRUCT (pr, pr_sel_t, 1);
|
||||||
pr_va_list_t args = P_STRUCT (pr, pr_va_list_t, 2);
|
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_RunError (pr, "%s does not respond to %s",
|
||||||
PR_GetString (pr, object_get_class_name (pr, receiver)),
|
PR_GetString (pr, object_get_class_name (pr, receiver)),
|
||||||
PR_GetString (pr, op->sel_id));
|
PR_GetString (pr, op->sel_id));
|
||||||
|
@ -365,7 +373,7 @@ pr_obj_msg_sendv (progs_t *pr)
|
||||||
args.count = 6;
|
args.count = 6;
|
||||||
memcpy (P_GPOINTER (pr, 2), G_GPOINTER (pr, args.list),
|
memcpy (P_GPOINTER (pr, 2), G_GPOINTER (pr, args.list),
|
||||||
args.count * 4 * pr->pr_param_size);
|
args.count * 4 * pr->pr_param_size);
|
||||||
call_function (pr, imp);
|
call_function (pr, method->method_imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -435,7 +443,7 @@ pr_obj_msgSend (progs_t *pr)
|
||||||
{
|
{
|
||||||
pr_id_t *self = &P_STRUCT (pr, pr_id_t, 0);
|
pr_id_t *self = &P_STRUCT (pr, pr_id_t, 0);
|
||||||
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
|
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
|
||||||
func_t imp;
|
pr_method_t *method;
|
||||||
|
|
||||||
if (!self) {
|
if (!self) {
|
||||||
R_INT (pr) = R_INT (pr);
|
R_INT (pr) = R_INT (pr);
|
||||||
|
@ -443,13 +451,13 @@ pr_obj_msgSend (progs_t *pr)
|
||||||
}
|
}
|
||||||
if (!_cmd)
|
if (!_cmd)
|
||||||
PR_RunError (pr, "null selector");
|
PR_RunError (pr, "null selector");
|
||||||
imp = obj_msg_lookup (pr, self, _cmd);
|
method = obj_msg_lookup (pr, self, _cmd);
|
||||||
if (!imp)
|
if (!method)
|
||||||
PR_RunError (pr, "%s does not respond to %s",
|
PR_RunError (pr, "%s does not respond to %s",
|
||||||
PR_GetString (pr, object_get_class_name (pr, self)),
|
PR_GetString (pr, object_get_class_name (pr, self)),
|
||||||
PR_GetString (pr, _cmd->sel_id));
|
PR_GetString (pr, _cmd->sel_id));
|
||||||
|
|
||||||
call_function (pr, imp);
|
call_function (pr, method->method_imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_super_t *super = &P_STRUCT (pr, pr_super_t, 0);
|
||||||
pr_sel_t *_cmd = &P_STRUCT (pr, pr_sel_t, 1);
|
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);
|
method = obj_msg_lookup_super (pr, super, _cmd);
|
||||||
if (!imp) {
|
if (!method) {
|
||||||
pr_id_t *self = &G_STRUCT (pr, pr_id_t, super->self);
|
pr_id_t *self = &G_STRUCT (pr, pr_id_t, super->self);
|
||||||
PR_RunError (pr, "%s does not respond to %s",
|
PR_RunError (pr, "%s does not respond to %s",
|
||||||
PR_GetString (pr, object_get_class_name (pr, self)),
|
PR_GetString (pr, object_get_class_name (pr, self)),
|
||||||
PR_GetString (pr, _cmd->sel_id));
|
PR_GetString (pr, _cmd->sel_id));
|
||||||
}
|
}
|
||||||
P_POINTER (pr, 0) = super->self;
|
P_POINTER (pr, 0) = super->self;
|
||||||
call_function (pr, imp);
|
call_function (pr, method->method_imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -518,9 +526,9 @@ pr_sel_get_type (progs_t *pr)
|
||||||
static void
|
static void
|
||||||
pr_sel_get_uid (progs_t *pr)
|
pr_sel_get_uid (progs_t *pr)
|
||||||
{
|
{
|
||||||
//const char *name = P_GSTRING (pr, 0);
|
const char *name = P_GSTRING (pr, 0);
|
||||||
//XXX
|
pr_sel_t *sel = Hash_Find (pr->selectors, name);
|
||||||
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
|
RETURN_POINTER (pr, sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -553,10 +561,10 @@ pr_class_get_class_method (progs_t *pr)
|
||||||
static void
|
static void
|
||||||
pr_class_get_instance_method (progs_t *pr)
|
pr_class_get_instance_method (progs_t *pr)
|
||||||
{
|
{
|
||||||
//pr_class_t *class = &P_STRUCT (pr, pr_class_t, 0);
|
pr_class_t *class = &P_STRUCT (pr, pr_class_t, 0);
|
||||||
//pr_sel_t *aSel = &P_STRUCT (pr, pr_sel_t, 1);
|
pr_sel_t *aSel = &P_STRUCT (pr, pr_sel_t, 1);
|
||||||
//XXX
|
pr_method_t *method = obj_find_message (pr, class, aSel);
|
||||||
PR_RunError (pr, "%s, not implemented", __FUNCTION__);
|
RETURN_POINTER (pr, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -934,6 +942,11 @@ PR_InitRuntime (progs_t *pr)
|
||||||
pr_class_t **class_list, **class;
|
pr_class_t **class_list, **class;
|
||||||
pr_category_t **category_list, **category;
|
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)
|
if (!pr->classes)
|
||||||
pr->classes = Hash_NewTable (1021, class_get_key, 0, pr);
|
pr->classes = Hash_NewTable (1021, class_get_key, 0, pr);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,11 +1,39 @@
|
||||||
integer (integer argc, string []argv) main =
|
integer (integer argc, string []argv) main =
|
||||||
{
|
{
|
||||||
local integer i;
|
local integer i;
|
||||||
|
local SEL sel;
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
print (argv[i]);
|
print (argv[i]);
|
||||||
print ("\n");
|
print ("\n");
|
||||||
}
|
}
|
||||||
local id foo = [[Foo alloc] init];
|
local id foo = [[Foo alloc] init];
|
||||||
[foo run];
|
[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;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue