mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
initial stab at supporting most of the obj runtime
This commit is contained in:
parent
60457ee7b8
commit
43e609241c
4 changed files with 999 additions and 118 deletions
|
@ -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 $<
|
||||
|
|
|
@ -22,3 +22,4 @@ menu.dat
|
|||
@srcdir@/options.qc
|
||||
@srcdir@/servlist.qc
|
||||
@srcdir@/menu.qc
|
||||
@srcdir@/object.r
|
||||
|
|
381
cs-code/object.r
Normal file
381
cs-code/object.r
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue