86 lines
1.9 KiB
C
86 lines
1.9 KiB
C
#include "MObject.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
static struct Object* alloc(struct Object* self);
|
|
static struct Object* retain(struct Object* self);
|
|
static struct Object* release(struct Object* self);
|
|
|
|
struct Method MObject_meta_methods[] = {
|
|
{ .sel = "alloc", .impl = alloc },
|
|
};
|
|
struct Class MObjectMetaClass = {
|
|
.class = &MObjectMetaClass,
|
|
.name = "MObject(meta)",
|
|
.super = nullptr,
|
|
.methods = MObject_meta_methods,
|
|
.methods_count = sizeof(MObject_meta_methods) / sizeof(struct Method),
|
|
};
|
|
|
|
struct Method MObject_methods[] = {
|
|
{ .sel = "retain", .impl = retain },
|
|
{ .sel = "release", .impl = release },
|
|
};
|
|
struct Class MObject = {
|
|
.class = &MObjectMetaClass,
|
|
.name = "MObject",
|
|
.super = nullptr,
|
|
.methods = MObject_methods,
|
|
.methods_count = sizeof(MObject_methods) / sizeof(struct Method),
|
|
};
|
|
|
|
struct Header
|
|
{
|
|
size_t retain_count;
|
|
};
|
|
|
|
static struct Object* alloc(struct Object* self)
|
|
{
|
|
if (!self) {
|
|
return nullptr;
|
|
}
|
|
|
|
struct Class* class = (struct Class*)self;
|
|
|
|
auto size = sizeof(struct Header) + sizeof(struct Object);
|
|
void* mem = malloc(size);
|
|
memset(mem, 0, size);
|
|
|
|
struct Header* header = (struct Header*)mem;
|
|
header->retain_count = 1;
|
|
|
|
struct Object* obj = (struct Object*)((uintptr_t)mem + sizeof(struct Header));
|
|
obj->class = class;
|
|
|
|
return obj;
|
|
}
|
|
|
|
static struct Object* retain(struct Object* self)
|
|
{
|
|
if (!self) {
|
|
return nullptr;
|
|
}
|
|
|
|
struct Header* header = (struct Header*)((uintptr_t)self - sizeof(struct Header));
|
|
header->retain_count += 1;
|
|
|
|
return self;
|
|
}
|
|
|
|
static struct Object* release(struct Object* self)
|
|
{
|
|
if (!self) {
|
|
return nullptr;
|
|
}
|
|
|
|
struct Header* header = (struct Header*)((uintptr_t)self - sizeof(struct Header));
|
|
header->retain_count -= 1;
|
|
if (header->retain_count <= 0) {
|
|
free(header);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|