Skip to content

Instantly share code, notes, and snippets.

@lighth7015
Created March 22, 2019 20:02
Show Gist options
  • Save lighth7015/422a3d712265993b2ae6cd722d7cf858 to your computer and use it in GitHub Desktop.
Save lighth7015/422a3d712265993b2ae6cd722d7cf858 to your computer and use it in GitHub Desktop.
Object type system
#define _GNU_SOURCE
#define STATIC_DECLARE_INIT(sym, name, id, ...) \
sym __attribute__ ((section (id))) name = { __VA_ARGS__ };
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
typedef struct object_typeinfo {
const char* name;
uint32_t type_id;
} type_info;
typedef struct object
{
const char signature[4];
type_info* type;
void* members;
void* instance;
uint32_t ref_cnt;
void* handles;
void* remote;
void* unused;
struct object *next,
*prev;
} *Handle;
typedef struct ListContainer {
uint32_t cv;
Handle root;
} ListContainer;
STATIC_DECLARE_INIT(struct ListContainer, container, ".handles", 0, 0);
void
__attribute__((constructor))
init() {
container.root = calloc(sizeof(struct object), 1);
}
void
__attribute__((destructor))
fini() {
Handle iter;
size_t index = 0;
if (container.root)
{
for ( iter = container.root
, index = 0
; iter
; iter = iter->next
, index ++ )
{
if (index > 0)
{
Handle node = iter->prev;
container.cv --;
free(node);
}
}
}
}
typedef void (*apply_fn)(ListContainer, type_info*, Handle);
void print_list(ListContainer container, type_info* typeinfo, Handle handle)
{
}
void list_apply(ListContainer container, apply_fn apply) {
for ( Handle iter = container.root
; iter
; iter = iter->next)
{
apply(container, iter->type, iter);
}
}
Handle append(ListContainer container, Handle node) {
if (container.root) {
for ( Handle iter = container.root
; iter
; iter = iter->next)
{
if (iter->next == NULL)
{
iter->next = node;
container.cv ++;
return node;
}
}
}
return NULL;
}
Handle index_of(ListContainer container, size_t id) {
size_t index = -1;
Handle iter = NULL;
if (container.root) {
for ( iter = container.root
, index = 0
; iter
; iter = iter->next
, index ++ )
{
if (index == id)
{
goto finished;
}
}
}
finished:
return iter;
}
size_t find(ListContainer container, Handle node) {
size_t index = -1;
if (container.root) {
Handle iter;
for ( iter = container.root
, index = 0
; iter
; iter = iter->next
, index ++ )
{
if (node == iter)
{
goto finished;
}
}
}
finished:
return index;
}
Handle append_at(ListContainer container, size_t index, Handle node) {
if (container.root && index >= 0) {
Handle iter;
size_t pos;
for ( iter = container.root
, pos = 0
; iter
; iter = iter->next
, pos ++ )
{
if (iter->next && (pos + 1) == index)
{
goto append_match;
}
}
goto finished;
append_match:
node->next = iter->next;
node->prev = iter->prev;
iter->next = node;
return node;
}
finished:
return NULL;
}
void remove_from(ListContainer container, size_t index)
{
Handle iter,
next,
prev;
size_t pos;
if (container.root && index > 0)
{
for ( iter = container.root
, pos = 0
; iter
; iter = iter->next
, pos ++ )
{
if (iter->next && (pos + 1) == index)
{
goto remove_found;
}
}
goto finished;
remove_found:
next = iter->next;
prev = iter->prev;
prev->next = next;
next->prev = prev;
free(iter);
finished:
return;
}
}
bool IsHandle(size_t index)
{
if (index > 0 && index < container.cv) {
Handle handle = index_of(container, index);
return handle && handle->type;
}
return false;
}
size_t count(ListContainer container) {
return container.cv;
}
Handle CreateHandle()
{
const char signature[4] = { 'O', 'b', 'j', 0 };
Handle obj = calloc(1, sizeof(struct object));
obj->type = calloc(1, sizeof(struct object_typeinfo));
memcpy((void *) obj->signature, &signature, 4);
container.cv ++;
return append(container, obj);
}
// Pretend to be object, living somewhere else
size_t Foo() {
Handle object = CreateHandle();
type_info* type = object->type;
char** addr = (char **) &type->name;
asprintf( addr, "%s", "Foo Object");
return find(container, object);
}
int main()
{
int nval = 42,
oval = 1;
printf("object's handle index is %zu. Container has %zu items.\n", Foo(), count(container));
printf("object's handle index is %zu. Container has %zu items.\n", Foo(), count(container));
printf("object's handle index is %zu. Container has %zu items.\n", Foo(), count(container));
printf("object's handle index is %zu. Container has %zu items.\n", Foo(), count(container));
printf("object's handle index is %zu. Container has %zu items.\n", Foo(), count(container));
printf("handle validity check: value %d %s a handle.\n", nval, IsHandle(nval)? "is": "is not");
printf("handle validity check: value %d %s a handle.\n", oval, IsHandle(oval)? "is": "is not");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment