Created
March 22, 2019 20:02
-
-
Save lighth7015/422a3d712265993b2ae6cd722d7cf858 to your computer and use it in GitHub Desktop.
Object type system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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