diff --git a/cs-code/Makefile.am b/cs-code/Makefile.am index 5a57d5941..cbc1d25e8 100644 --- a/cs-code/Makefile.am +++ b/cs-code/Makefile.am @@ -22,7 +22,7 @@ menu_src= \ cbuf_def.qc cmd_def.qc controls_o.qc cvar_def.qc draw_def.qc file_def.qc \ game_def.qc inputline_def.qc inputline_util.qc key_defs.qc menu.qc \ menu_def.qc menu_pics.qc menu_util.qc options.qc options_util.qc \ - servlist.qc string_def.qc stringh_def.qc + servlist.qc string_def.qc stringh_def.qc object.r menu.dat$(GZ): menu.src $(menu_src) $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -P $< diff --git a/cs-code/menu.src.in b/cs-code/menu.src.in index b13e30ff7..031ee14cd 100644 --- a/cs-code/menu.src.in +++ b/cs-code/menu.src.in @@ -22,3 +22,4 @@ menu.dat @srcdir@/options.qc @srcdir@/servlist.qc @srcdir@/menu.qc +@srcdir@/object.r diff --git a/cs-code/object.r b/cs-code/object.r new file mode 100644 index 000000000..d31dae7d3 --- /dev/null +++ b/cs-code/object.r @@ -0,0 +1,381 @@ +typedef enum { + NO, + YES, +} BOOL; + +void (id object, integer code, string fmt, ...) obj_error = #0; +void (id object, integer code, string fmt, ...) obj_verror = #0; +//obj_error_handler (objc_error_handler func) obj_set_error_handler = #0; +IMP (id receiver, SEL op) obj_msg_lookup = #0; +IMP (id receiver, SEL op) obj_msg_lookup_super = #0; +//retval_t (id receiver, SEL op, arglist_t) obj_msg_sendv = #0; +(void []) (integer size) obj_malloc = #0; +(void []) (integer size) obj_atomic_malloc = #0; +(void []) (integer size) obj_valloc = #0; +(void []) (void [] mem, integer size) obj_realloc = #0; +(void []) (integer nelem, integer size) obj_calloc = #0; +void (void [] mem) obj_free = #0; +//(void []) (void) obj_get_uninstalled_dtable = #0; + +Class (string name) obj_get_class = #0; +Class (string name) obj_lookup_class = #0; +//Class (void [][] enum_stage) obj_next_class = #0; + +string (SEL selector) sel_get_name = #0; +string (SEL selector) sel_get_type = #0; +SEL (string name) sel_get_uid = #0; +SEL (string name) sel_get_any_uid = #0; +SEL (string name) sel_get_any_typed_uid = #0; +SEL (string name) sel_get_typed_uid = #0; +SEL (string name) sel_register_name = #0; +SEL (string name, string type) sel_register_typed_name = #0; +BOOL (SEL aSel) sel_is_mapped = #0; + +Method (Class class, SEL aSel) class_get_class_method = 0; +Method (Class class, SEL aSel) class_get_instance_method = 0; +Class (Class imposter, Class superclass) class_pose_as = #0; +id (Class class) class_create_instance = #0; +string (Class class) class_get_class_name = #0; +integer (Class class) class_get_instance_size = #0; +Class (Class class) class_get_meta_class = #0; +Class (Class class) class_get_super_class = #0; +integer (Class class) class_get_version = #0; +BOOL (Class class) class_is_class = #0; +BOOL (Class class) class_is_meta_class = #0; +void (Class class, integer version) class_set_version = #0; +(void []) (Class class) class_get_gc_object_type = #0; +void (Class class, string ivarname, BOOL gcInvisible) class_ivar_set_gcinvisible = #0; + +IMP (Method method) method_get_imp = #0; +IMP (Class class, SEL sel) get_imp = #0; + +id (id object) object_copy = #0; +id (id object) object_dispose = #0; +Class (id object) object_get_class = #0; +string (id object) object_get_class_name = #0; +Class (id object) object_get_meta_class = #0; +Class (id object) object_get_super_class = #0; +BOOL (id object) object_is_class = #0; +BOOL (id object) object_is_instance = #0; +BOOL (id object) object_is_meta_class = #0; + +@interface Object +{ + Class isa; +} + ++initialize; +-init; + ++new; ++alloc; +-free; +-copy; +-shallowCopy; +-deepen; +-deepCopy; + +-(Class)class; +-(Class)superClass; +-(Class)metaClass; +-(string)name; + +-self; +-(integer)hash; +-(BOOL)isEqual:anObject; +-(integer)compare:anotherObject; + +-(BOOL)isMetaClass; +-(BOOL)isClass; +-(BOOL)isInstance; + +-(BOOL)isKindOf:(Class)aClassObject; +-(BOOL)isMemberOf:(Class)aClassObject; +-(BOOL)isKindOfClassNamed:(string)aClassName; +-(BOOL)isMemberOfClassNamed:(string)aClassName; + ++(BOOL)instancesRespondTo:(SEL)aSel; +-(BOOL)respondsTo:(SEL)aSel; + ++(BOOL)conformsTo:(Protocol)aProtocol; +-(BOOL)conformsTo:(Protocol)aProtocol; + ++(IMP)instanceMethodFor:(SEL)aSel; +-(IMP)methodFor:(SEL)aSel; +//+(struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel; +//-(struct objc_method_description *)descriptionForMethod:(SEL)aSel; + +-perform:(SEL)aSel; +-perform:(SEL)aSel with:anObject; +-perform:(SEL)aSel with:anObject1 with:anObject2; + +//-(retval_t)forward:(SEL)aSel :(arglist_t)argFrame; +//-(retval_t)performv:(SEL)aSel :(arglist_t)argFrame; + ++poseAs:(Class)aClassObject; +-(Class)transmuteClassTo:(Class)aClassObject; + +-subclassResponsibility:(SEL)aSel; +-notImplemented:(SEL)aSel; +-shouldNotImplement:(SEL)aSel; + +-doesNotRecognize:(SEL)aSel; +-error:(string)aString, ...; + +//+(integer)version; +//+setVersion:(integer)aVersion; +//+(integer)streamVersion: (TypedStream*)aStream; + +//-read: (TypedStream*)aStream; +//-write: (TypedStream*)aStream; +//-awake; +@end + +@implementation Object ++initialize +{ + return self; +} + +-init +{ + return self; +} + ++new +{ + return [[self alloc] init]; +} + ++alloc +{ + return class_create_instance (self); +} + +-free +{ + return object_dispose (self); +} + +-copy +{ + return [[self shallowCopy] deepen]; +} + +-shallowCopy +{ + return object_copy (self); +} + +-deepen +{ + return self; +} + +-deepCopy +{ + return [self copy]; +} + +-(Class)class +{ + return object_get_class (self); +} + +-(Class)superClass +{ + return object_get_super_class (self); +} + +-(Class)metaClass +{ + return object_get_meta_class (self); +} + +-(string)name +{ + return object_get_class_name (self); +} + +-self +{ + return self; +} + +-(integer)hash = #0; // can't cast pointer to integer + +-(BOOL)isEqual:anObject +{ + return id(self) == anObject; //FIXME shouldn't need cast +} + +-(integer)compare:anotherObject = #0; // can only == or != pointers + +-(BOOL)isMetaClass +{ + return NO; +} + +-(BOOL)isClass +{ + return object_is_class (self); +} + +-(BOOL)isInstance +{ + return object_is_instance (self); +} + +-(BOOL)isKindOf:(Class)aClassObject +{ + local Class class; + + for (class = self.isa; class; class = class_get_super_class (class)) + if (class == aClassObject) + return YES; + return NO; +} + +-(BOOL)isMemberOf:(Class)aClassObject +{ + return self.isa == aClassObject; +} + +-(BOOL)isKindOfClassNamed:(string)aClassName +{ + local Class class; + if (aClassName) + for (class = self.isa; class; class = class_get_super_class (class)) + if (class_get_class_name (class) == aClassName) + return YES; + return NO; +} + +-(BOOL)isMemberOfClassNamed:(string)aClassName +{ + local Class class; + if (aClassName) + for (class = self.isa; class; class = class_get_super_class (class)) + if (class_get_class_name (class) == aClassName) + return YES; + return aClassName && class_get_class_name (self.isa) == aClassName; +} + ++(BOOL)instancesRespondTo:(SEL)aSel +{ + return class_get_instance_method (self, aSel) != NIL; +} + +-(BOOL)respondsTo:(SEL)aSel +{ + return (object_is_instance (self) + ? class_get_instance_method (self.isa, aSel) + : class_get_class_method (self.isa, aSel)) != NIL; +} + ++(BOOL)conformsTo:(Protocol)aProtocol = #0; +-(BOOL)conformsTo:(Protocol)aProtocol +{ + return [[self class] conformsTo:aProtocol]; +} + ++(IMP)instanceMethodFor:(SEL)aSel +{ + return method_get_imp (class_get_instance_method (self, aSel)); +} + +-(IMP)methodFor:(SEL)aSel +{ + return method_get_imp (object_is_instance (self) + ? class_get_instance_method (self.isa, aSel) + : class_get_class_method (self.isa, aSel)); +} + +//+(struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel = #0; +//-(struct objc_method_description *)descriptionForMethod:(SEL)aSel = #0; + +-perform:(SEL)aSel +{ + local IMP msg = obj_msg_lookup (self, aSel); + + if (!msg) + return [self error:"invalid selector passed to %s", + sel_get_name (_cmd)]; + return msg (self, aSel); +} + +-perform:(SEL)aSel with:anObject +{ + local IMP msg = obj_msg_lookup (self, aSel); + + if (!msg) + return [self error:"invalid selector passed to %s", + sel_get_name (_cmd)]; + return msg (self, aSel, anObject); +} + +-perform:(SEL)aSel with:anObject1 with:anObject2 +{ + local IMP msg = obj_msg_lookup (self, aSel); + + if (!msg) + return [self error:"invalid selector passed to %s", + sel_get_name (_cmd)]; + return msg (self, aSel, anObject1, anObject2); +} + +//-(retval_t)forward:(SEL)aSel :(arglist_t)argFrame = #0; +//-(retval_t)performv:(SEL)aSel :(arglist_t)argFrame = #0; + ++poseAs:(Class)aClassObject +{ + return class_pose_as (self, aClassObject); +} + +-(Class)transmuteClassTo:(Class)aClassObject +{ + if (object_is_instance (self)) + if (class_is_class (aClassObject)) + if (class_get_instance_size (aClassObject) == class_get_instance_size (isa)) + if ([self isKindOf:aClassObject]) { + local Class old_isa = isa; + isa = aClassObject; + return old_isa; + } + return NIL; +} + +-subclassResponsibility:(SEL)aSel +{ + return [self error:"subclass should override %s", + sel_get_name(aSel)]; +} + +-notImplemented:(SEL)aSel +{ + return [self error:"methos %s not implemented", + sel_get_name(aSel)]; +} + +-shouldNotImplement:(SEL)aSel +{ + return [self error:"%s should not implement %s", + object_get_class_name (self), sel_get_name(aSel)]; +} + +-doesNotRecognize:(SEL)aSel +{ + return [self error:"%s does not recognize %s", + object_get_class_name (self), sel_get_name(aSel)]; +} + +-error:(string)aString, ... = #0; + +//+(integer)version = #0; +//+setVersion:(integer)aVersion = #0; +//+(integer)streamVersion: (TypedStream*)aStream = #0; + +//-read: (TypedStream*)aStream = #0; +//-write: (TypedStream*)aStream = #0; +//-awake = #0; +@end diff --git a/libs/gamecode/engine/pr_obj.c b/libs/gamecode/engine/pr_obj.c index 39702fe56..976f72486 100644 --- a/libs/gamecode/engine/pr_obj.c +++ b/libs/gamecode/engine/pr_obj.c @@ -48,89 +48,19 @@ static const char rcsid[] = #include "compat.h" +static inline pointer_t +POINTER_TO_PROG (progs_t *pr, void *p) +{ + return p ? (pr_type_t *) p - pr->pr_globals : 0; +} + + static const char * class_get_key (void *c, void *pr) { return PR_GetString ((progs_t *)pr, ((pr_class_t *)c)->name); } -static func_t -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; - int i; - - while (c) { - if (c->methods) { - method_list = &G_STRUCT (pr, pr_method_list_t, c->methods); - for (i = 0, method = method_list->method_list; - i < method_list->method_count; i++) { - if (method->method_name.sel_id == selector->sel_id) - return method->method_imp; - } - } - c = c->super_class ? &G_STRUCT (pr, pr_class_t, c->super_class) : 0; - } - return 0; -} - -static void -pr_obj_msgSend (progs_t *pr) -{ - pointer_t _self = G_INT (pr, OFS_PARM0); - pointer_t __cmd = G_INT (pr, OFS_PARM1); - pr_class_t *self; - pr_sel_t *_cmd; - func_t imp; - - if (!_self) { - G_INT (pr, OFS_RETURN) = _self; - return; - } - if (!__cmd) - PR_RunError (pr, "null selector"); - self = &G_STRUCT (pr, pr_class_t, _self); - _cmd = &G_STRUCT (pr, pr_sel_t, __cmd); - imp = obj_find_message (pr, self, _cmd); - if (!imp) - PR_RunError (pr, "%s does not respond to %s", - PR_GetString (pr, self->name), - PR_GetString (pr, _cmd->sel_id)); - PR_ExecuteProgram (pr, imp); -} - -static void -pr_obj_msgSend_super (progs_t *pr) -{ - pointer_t _self = G_INT (pr, OFS_PARM0); - pointer_t __cmd = G_INT (pr, OFS_PARM1); - pr_class_t *self; - pr_class_t *super; - pr_sel_t *_cmd; - func_t imp; - - if (!_self) { - G_INT (pr, OFS_RETURN) = _self; - return; - } - if (!__cmd) - PR_RunError (pr, "null selector"); - self = &G_STRUCT (pr, pr_class_t, _self); - _cmd = &G_STRUCT (pr, pr_sel_t, __cmd); - if (!self->super_class) - PR_RunError (pr, "%s has no super class", - PR_GetString (pr, self->name)); - super = &G_STRUCT (pr, pr_class_t, self->super_class); - imp = obj_find_message (pr, super, _cmd); - if (!imp) - PR_RunError (pr, "%s does not respond to %s", - PR_GetString (pr, super->name), - PR_GetString (pr, _cmd->sel_id)); - PR_ExecuteProgram (pr, imp); -} - static void dump_ivars (progs_t *pr, pointer_t _ivars) { @@ -148,6 +78,8 @@ dump_ivars (progs_t *pr, pointer_t _ivars) } } +//==================================================================== + static void pr___obj_exec_class (progs_t *pr) { @@ -235,55 +167,622 @@ pr___obj_exec_class (progs_t *pr) //developer->int_val = d; } +//==================================================================== + +static func_t +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; + int i; + + while (c) { + if (c->methods) { + method_list = &G_STRUCT (pr, pr_method_list_t, c->methods); + for (i = 0, method = method_list->method_list; + i < method_list->method_count; i++) { + if (method->method_name.sel_id == selector->sel_id) + return method->method_imp; + } + } + c = c->super_class ? &G_STRUCT (pr, pr_class_t, c->super_class) : 0; + } + return 0; +} + static void -pr_return_self (progs_t *pr) +pr_obj_error (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_verror (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_set_error_handler (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_msg_lookup (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_msg_lookup_super (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_msg_sendv (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_malloc (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_atomic_malloc (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_valloc (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_realloc (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_calloc (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_free (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_get_uninstalled_dtable (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_msgSend (progs_t *pr) +{ + pointer_t _self = G_INT (pr, OFS_PARM0); + pointer_t __cmd = G_INT (pr, OFS_PARM1); + pr_class_t *self; + pr_sel_t *_cmd; + func_t imp; + + if (!_self) { + G_INT (pr, OFS_RETURN) = _self; + return; + } + if (!__cmd) + PR_RunError (pr, "null selector"); + self = &G_STRUCT (pr, pr_class_t, _self); + _cmd = &G_STRUCT (pr, pr_sel_t, __cmd); + imp = obj_find_message (pr, self, _cmd); + if (!imp) + PR_RunError (pr, "%s does not respond to %s", + PR_GetString (pr, self->name), + PR_GetString (pr, _cmd->sel_id)); + PR_ExecuteProgram (pr, imp); +} + +static void +pr_obj_msgSend_super (progs_t *pr) +{ + pointer_t _self = G_INT (pr, OFS_PARM0); + pointer_t __cmd = G_INT (pr, OFS_PARM1); + pr_class_t *self; + pr_class_t *super; + pr_sel_t *_cmd; + func_t imp; + + if (!_self) { + G_INT (pr, OFS_RETURN) = _self; + return; + } + if (!__cmd) + PR_RunError (pr, "null selector"); + self = &G_STRUCT (pr, pr_class_t, _self); + _cmd = &G_STRUCT (pr, pr_sel_t, __cmd); + if (!self->super_class) + PR_RunError (pr, "%s has no super class", + PR_GetString (pr, self->name)); + super = &G_STRUCT (pr, pr_class_t, self->super_class); + imp = obj_find_message (pr, super, _cmd); + if (!imp) + PR_RunError (pr, "%s does not respond to %s", + PR_GetString (pr, super->name), + PR_GetString (pr, _cmd->sel_id)); + PR_ExecuteProgram (pr, imp); +} + +static void +pr_obj_get_class (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_lookup_class (progs_t *pr) +{ + //XXX +} + +static void +pr_obj_next_class (progs_t *pr) +{ + //XXX +} + +//==================================================================== + +static void +pr_sel_get_name (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_get_type (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_get_uid (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_get_any_uid (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_get_any_typed_uid (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_get_typed_uid (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_register_name (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_register_typed_name (progs_t *pr) +{ + //XXX +} + +static void +pr_sel_is_mapped (progs_t *pr) +{ + //XXX +} + +//==================================================================== + +static void +pr_class_get_class_method (progs_t *pr) +{ + //XXX +} + +static void +pr_class_get_instance_method (progs_t *pr) +{ + //XXX +} + +static void +pr_class_pose_as (progs_t *pr) +{ + //XXX +} + +static inline pr_id_t * +class_create_instance (progs_t *pr, pr_class_t *class) +{ + int size = class->instance_size * sizeof (pr_type_t); + pr_id_t *id; + + id = PR_Zone_Malloc (pr, size); + memset (id, 0, size); + id->class_pointer = POINTER_TO_PROG (pr, class); + return id; +} + +static void +pr_class_create_instance (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + pr_id_t *id = class_create_instance (pr, class); + + G_INT (pr, OFS_RETURN) = POINTER_TO_PROG (pr, id); +} + +static void +pr_class_get_class_name (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class) ? class->name + : PR_SetString (pr, "Nil"); +} + +static void +pr_class_get_instance_size (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class) ? class->instance_size : 0; +} + +static void +pr_class_get_meta_class (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class) ? class->class_pointer : 0; +} + +static void +pr_class_get_super_class (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class) ? class->super_class : 0; +} + +static void +pr_class_get_version (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class) ? class->version : -1; +} + +static void +pr_class_is_class (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class); +} + +static void +pr_class_is_meta_class (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISMETA (class); +} + +static void +pr_class_set_version (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + if (PR_CLS_ISCLASS (class)) + class->version = G_INT (pr, OFS_PARM1); +} + +static void +pr_class_get_gc_object_type (progs_t *pr) +{ + pr_class_t *class = &G_STRUCT (pr, pr_class_t, G_INT (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class) ? class->gc_object_type : 0; +} + +static void +pr_class_ivar_set_gcinvisible (progs_t *pr) +{ + //XXX +} + +//==================================================================== + +static void +pr_method_get_imp (progs_t *pr) +{ + //XXX +} + +static void +pr_get_imp (progs_t *pr) +{ + //XXX +} + +//==================================================================== + +static void +pr_object_dispose (progs_t *pr) +{ + pr_id_t *object = &G_STRUCT (pr, pr_id_t, G_INT (pr, OFS_PARM0)); + PR_Zone_Free (pr, object); +} + +static void +pr_object_copy (progs_t *pr) +{ + pr_id_t *object = &G_STRUCT (pr, pr_id_t, G_INT (pr, OFS_PARM0)); + pr_class_t *class = &G_STRUCT (pr, pr_class_t, object->class_pointer); + pr_id_t *id; + + id = class_create_instance (pr, class); + memcpy (id, object, sizeof (pr_type_t) * class->instance_size); + G_INT (pr, OFS_RETURN) = POINTER_TO_PROG (pr, id); +} + +static void +pr_object_get_class (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_id_t *object = &G_STRUCT (pr, pr_id_t, _object); + pr_class_t *class; + + if (_object) { + class = &G_STRUCT (pr, pr_class_t, object->class_pointer); + if (PR_CLS_ISCLASS (class)) { + G_INT (pr, OFS_RETURN) = POINTER_TO_PROG (pr, class); + return; + } + if (PR_CLS_ISMETA (class)) { + G_INT (pr, OFS_RETURN) = _object; + return; + } + } + G_INT (pr, OFS_RETURN) = 0; +} + +static void +pr_object_get_super_class (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_id_t *object = &G_STRUCT (pr, pr_id_t, _object); + pr_class_t *class; + + if (_object) { + class = &G_STRUCT (pr, pr_class_t, object->class_pointer); + if (PR_CLS_ISCLASS (class)) { + G_INT (pr, OFS_RETURN) = class->super_class; + return; + } + if (PR_CLS_ISMETA (class)) { + G_INT (pr, OFS_RETURN) = ((pr_class_t *)object)->super_class; + return; + } + } + G_INT (pr, OFS_RETURN) = 0; +} + +static void +pr_object_get_meta_class (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_id_t *object = &G_STRUCT (pr, pr_id_t, _object); + pr_class_t *class; + + if (_object) { + class = &G_STRUCT (pr, pr_class_t, object->class_pointer); + if (PR_CLS_ISCLASS (class)) { + G_INT (pr, OFS_RETURN) = class->class_pointer; + return; + } + if (PR_CLS_ISMETA (class)) { + G_INT (pr, OFS_RETURN) = ((pr_class_t *)object)->class_pointer; + return; + } + } + G_INT (pr, OFS_RETURN) = 0; +} + +static void +pr_object_get_class_name (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_id_t *object = &G_STRUCT (pr, pr_id_t, _object); + pr_class_t *class; + + if (_object) { + class = &G_STRUCT (pr, pr_class_t, object->class_pointer); + if (PR_CLS_ISCLASS (class)) { + G_INT (pr, OFS_RETURN) = class->name; + return; + } + if (PR_CLS_ISMETA (class)) { + G_INT (pr, OFS_RETURN) = ((pr_class_t *)object)->name; + return; + } + } + RETURN_STRING (pr, "Nil"); +} + +static void +pr_object_is_class (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_class_t *object = &G_STRUCT (pr, pr_class_t, _object); + + if (_object) { + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (object); + return; + } + G_INT (pr, OFS_RETURN) = 0; +} + +static void +pr_object_is_instance (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_id_t *object = &G_STRUCT (pr, pr_id_t, _object); + pr_class_t *class; + + if (_object) { + class = &G_STRUCT (pr, pr_class_t, object->class_pointer); + G_INT (pr, OFS_RETURN) = PR_CLS_ISCLASS (class); + return; + } + G_INT (pr, OFS_RETURN) = 0; +} + +static void +pr_object_is_meta_class (progs_t *pr) +{ + pointer_t _object = G_INT (pr, OFS_PARM0); + pr_class_t *object = &G_STRUCT (pr, pr_class_t, _object); + + if (_object) { + G_INT (pr, OFS_RETURN) = PR_CLS_ISMETA (object); + return; + } + G_INT (pr, OFS_RETURN) = 0; +} + +//==================================================================== + +static void +pr__i_Object__hash (progs_t *pr) { G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0); } +static void +pr__i_Object__compare (progs_t *pr) +{ + int ret; + ret = G_INT (pr, OFS_PARM0) != G_INT (pr, OFS_PARM2); + if (ret) { + ret = G_INT (pr, OFS_PARM0) > G_INT (pr, OFS_PARM2); + if (!ret) + ret = -1; + } + G_INT (pr, OFS_RETURN) = ret; +} + +static void +pr__c_Object__conformsTo (progs_t *pr) +{ + //XXX +} + +static void +pr__i_Object__error (progs_t *pr) +{ + //XXX +} + +//==================================================================== + +static struct { + const char *name; + void (*func)(progs_t *pr); +} obj_methods [] = { + {"__obj_exec_class", pr___obj_exec_class}, + + {"obj_error", pr_obj_error}, + {"obj_verror", pr_obj_verror}, + {"obj_set_error_handler", pr_obj_set_error_handler}, + {"obj_msg_lookup", pr_obj_msg_lookup}, + {"obj_msg_lookup_super", pr_obj_msg_lookup_super}, + {"obj_msg_sendv", pr_obj_msg_sendv}, + {"obj_malloc", pr_obj_malloc}, + {"obj_atomic_malloc", pr_obj_atomic_malloc}, + {"obj_valloc", pr_obj_valloc}, + {"obj_realloc", pr_obj_realloc}, + {"obj_calloc", pr_obj_calloc}, + {"obj_free", pr_obj_free}, + {"obj_get_uninstalled_dtable", pr_obj_get_uninstalled_dtable}, + {"obj_msgSend", pr_obj_msgSend}, + {"obj_msgSend_super", pr_obj_msgSend_super}, + + {"obj_get_class", pr_obj_get_class}, + {"obj_lookup_class", pr_obj_lookup_class}, + {"obj_next_class", pr_obj_next_class}, + + {"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}, + {"class_get_instance_method", pr_class_get_instance_method}, + {"class_pose_as", pr_class_pose_as}, + {"class_create_instance", pr_class_create_instance}, + {"class_get_class_name", pr_class_get_class_name}, + {"class_get_instance_size", pr_class_get_instance_size}, + {"class_get_meta_class", pr_class_get_meta_class}, + {"class_get_super_class", pr_class_get_super_class}, + {"class_get_version", pr_class_get_version}, + {"class_is_class", pr_class_is_class}, + {"class_is_meta_class", pr_class_is_meta_class}, + {"class_set_version", pr_class_set_version}, + {"class_get_gc_object_type", pr_class_get_gc_object_type}, + {"class_ivar_set_gcinvisible", pr_class_ivar_set_gcinvisible}, + + {"method_get_imp", pr_method_get_imp}, + {"get_imp", pr_get_imp}, + + {"object_copy", pr_object_copy}, + {"object_dispose", pr_object_dispose}, + {"object_get_class", pr_object_get_class}, + {"object_get_class_name", pr_object_get_class_name}, + {"object_get_meta_class", pr_object_get_meta_class}, + {"object_get_super_class", pr_object_get_super_class}, + {"object_is_class", pr_object_is_class}, + {"object_is_instance", pr_object_is_instance}, + {"object_is_meta_class", pr_object_is_meta_class}, + + {"_i_Object__hash", pr__i_Object__hash}, + {"_i_Object__compare", pr__i_Object__compare}, + {"_c_Object__conformsTo", pr__c_Object__conformsTo}, + {"_i_Object__error", pr__i_Object__error}, +}; + void PR_Obj_Progs_Init (progs_t *pr) { - PR_AddBuiltin (pr, "obj_msgSend", pr_obj_msgSend, -1); - PR_AddBuiltin (pr, "obj_msgSend_super", pr_obj_msgSend_super, -1); - PR_AddBuiltin (pr, "__obj_exec_class", pr___obj_exec_class, -1); + int i; - PR_AddBuiltin (pr, "_c_Object__initialize", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__init", pr_return_self, -1); - PR_AddBuiltin (pr, "_c_Object__alloc", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__free", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__shallowCopy", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__deepen", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__class", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__superClass", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__metaClass", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__name", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__self", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__hash", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isEqual", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__compare", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isMetaClass", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isClass", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isInstance", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isKindOf", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isMemberOf", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isKindOfClassNamed", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__isMemberOfClassNamed", pr_return_self, -1); - PR_AddBuiltin (pr, "_c_Object__instancesRespondTo", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__respondsTo", pr_return_self, -1); - PR_AddBuiltin (pr, "_c_Object__conformsTo", pr_return_self, -1); - PR_AddBuiltin (pr, "_c_Object__instanceMethodFor", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__methodFor", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__perform", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__perform_with", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__perform_with_with", pr_return_self, -1); - PR_AddBuiltin (pr, "_c_Object__poseAs", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__transmuteClassTo", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__subclassResponsibility", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__notImplemented", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__shouldNotImplement", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__doesNotRecognize", pr_return_self, -1); - PR_AddBuiltin (pr, "_i_Object__error", pr_return_self, -1); + for (i = 0; i < sizeof (obj_methods) / sizeof (obj_methods[0]); i++) { + PR_AddBuiltin (pr, obj_methods[i].name, obj_methods[i].func, -1); + } } void