mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
Move retainCount out of Object.
Going by "standard" Objective-C, retainCount really doesn't belong in Object itself. The way GNUStep does it is to stash retainCount in memory just below the object by allocating extra bytes for the count and returning a pointer just beyond those extra bytes. Now Ruamoko does the same. This fixes the inconsistencies in structure layouts for Protocol and class structs between qfcc generated (internal) structs and user visible structs.
This commit is contained in:
parent
377f8f9d56
commit
6b46cde7c8
4 changed files with 43 additions and 11 deletions
|
@ -1008,6 +1008,27 @@ rua_obj_msg_sendv (progs_t *pr)
|
|||
PR_CallFunction (pr, imp);
|
||||
}
|
||||
|
||||
static void
|
||||
rua_obj_increment_retaincount (progs_t *pr)
|
||||
{
|
||||
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
|
||||
R_INT (pr) = ++(*--obj).integer_var;
|
||||
}
|
||||
|
||||
static void
|
||||
rua_obj_decrement_retaincount (progs_t *pr)
|
||||
{
|
||||
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
|
||||
R_INT (pr) = --(*--obj).integer_var;
|
||||
}
|
||||
|
||||
static void
|
||||
rua_obj_get_retaincount (progs_t *pr)
|
||||
{
|
||||
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
|
||||
R_INT (pr) = (*--obj).integer_var;
|
||||
}
|
||||
|
||||
static void
|
||||
rua_obj_malloc (progs_t *pr)
|
||||
{
|
||||
|
@ -1245,11 +1266,13 @@ rua_class_pose_as (progs_t *pr)
|
|||
static inline pr_id_t *
|
||||
class_create_instance (progs_t *pr, pr_class_t *class)
|
||||
{
|
||||
int size = class->instance_size * sizeof (pr_type_t);
|
||||
int size = (class->instance_size + 1) * sizeof (pr_type_t);
|
||||
pr_type_t *mem;
|
||||
pr_id_t *id;
|
||||
|
||||
id = PR_Zone_Malloc (pr, size);
|
||||
memset (id, 0, size);
|
||||
mem = PR_Zone_Malloc (pr, size);
|
||||
// redundant memset (id, 0, size);
|
||||
id = (pr_id_t *) (mem + 1);
|
||||
id->class_pointer = PR_SetPointer (pr, class);
|
||||
return id;
|
||||
}
|
||||
|
@ -1363,7 +1386,8 @@ static void
|
|||
rua_object_dispose (progs_t *pr)
|
||||
{
|
||||
pr_id_t *object = &P_STRUCT (pr, pr_id_t, 0);
|
||||
PR_Zone_Free (pr, object);
|
||||
pr_type_t *mem = (pr_type_t *) object;
|
||||
PR_Zone_Free (pr, mem - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1375,6 +1399,8 @@ rua_object_copy (progs_t *pr)
|
|||
|
||||
id = class_create_instance (pr, class);
|
||||
memcpy (id, object, sizeof (pr_type_t) * class->instance_size);
|
||||
// copy the retain count
|
||||
((pr_type_t *) id)[-1] = ((pr_type_t *) object)[-1];
|
||||
RETURN_POINTER (pr, id);
|
||||
}
|
||||
|
||||
|
@ -1522,6 +1548,9 @@ static builtin_t obj_methods [] = {
|
|||
{"obj_msg_lookup", rua_obj_msg_lookup, -1},
|
||||
{"obj_msg_lookup_super", rua_obj_msg_lookup_super, -1},
|
||||
{"obj_msg_sendv", rua_obj_msg_sendv, -1},
|
||||
{"obj_increment_retaincount", rua_obj_increment_retaincount, -1},
|
||||
{"obj_decrement_retaincount", rua_obj_decrement_retaincount, -1},
|
||||
{"obj_get_retaincount", rua_obj_get_retaincount, -1},
|
||||
{"obj_malloc", rua_obj_malloc, -1},
|
||||
{"obj_atomic_malloc", rua_obj_atomic_malloc, -1},
|
||||
{"obj_valloc", rua_obj_valloc, -1},
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
@interface Object <Object>
|
||||
{
|
||||
Class isa;
|
||||
unsigned retainCount;
|
||||
}
|
||||
|
||||
+ (id) alloc;
|
||||
|
|
|
@ -28,6 +28,8 @@ typedef enum {
|
|||
@extern IMP obj_msg_lookup (id receiver, SEL op);
|
||||
@extern IMP obj_msg_lookup_super (Super class, SEL op);
|
||||
@extern @param obj_msg_sendv (id receiver, SEL op, @va_list args);
|
||||
@extern BOOL obj_decrement_ref_was_zero (id object);
|
||||
@extern BOOL obj_increment_ref_was_zero (id object);
|
||||
@extern void *obj_malloc (int size);
|
||||
@extern void *obj_atomic_malloc (int size);
|
||||
@extern void *obj_valloc (int size);
|
||||
|
|
|
@ -10,6 +10,9 @@ IMP (Super class, SEL op) obj_msg_lookup_super = #0;
|
|||
id (id receiver, SEL op, ...) obj_msgSend = #0;
|
||||
id obj_msgSend_super (Super *class, SEL op, ...) = #0;
|
||||
@param (id receiver, SEL op, @va_list args) obj_msg_sendv = #0;
|
||||
int obj_decrement_retaincount (id object) = #0;
|
||||
int obj_increment_retaincount (id object) = #0;
|
||||
int obj_get_retaincount (id object) = #0;
|
||||
void *obj_malloc (int size) = #0;
|
||||
void *obj_atomic_malloc (int size) = #0;
|
||||
void *obj_valloc (int size) = #0;
|
||||
|
@ -149,8 +152,7 @@ BOOL (id object) object_is_meta_class = #0;
|
|||
|
||||
- (id) init
|
||||
{
|
||||
retainCount = 1;
|
||||
|
||||
[self retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -282,16 +284,16 @@ BOOL (id object) object_is_meta_class = #0;
|
|||
*/
|
||||
- (id) retain
|
||||
{
|
||||
retainCount = [self retainCount] + 1;
|
||||
obj_increment_retaincount (self);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (/*oneway*/ void) release
|
||||
{
|
||||
if ([self retainCount] == 1) // don't let retain count actually reach zero
|
||||
if ([self retainCount] == 1) // don't let retain count reach zero
|
||||
[self dealloc];
|
||||
else
|
||||
retainCount--;
|
||||
obj_decrement_retaincount (self);
|
||||
}
|
||||
|
||||
- (id) autorelease
|
||||
|
@ -302,7 +304,7 @@ BOOL (id object) object_is_meta_class = #0;
|
|||
|
||||
- (unsigned) retainCount
|
||||
{
|
||||
return retainCount;
|
||||
return obj_get_retaincount (self);
|
||||
}
|
||||
/*
|
||||
CONVENIENCE METHODS
|
||||
|
|
Loading…
Reference in a new issue