Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
Class.c File Reference
#include "Config.h"
#include <assert.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Class.h"
#include "Object.h"

Go to the source code of this file.

Functions

ident _alloc (Class *clazz)
 Instantiate a type through the given Class.
 
ident _cast (const Class *clazz, const ident obj)
 Perform a type-checking cast.
 
Class_initialize (const ClassDef *def)
 Initializes the given Class.
 
ClassclassForName (const char *name)
 
ident release (ident obj)
 Atomically decrement the given Object's reference count. If the resulting reference count is 0, the Object is deallocated.
 
ident retain (ident obj)
 Atomically increment the given Object's reference count.
 
static void setup (void)
 Called when initializing Object to setup Objectively.
 
static void teardown (void)
 Called atexit to teardown Objectively.
 

Variables

static Class_classes
 
size_t _pageSize
 

Function Documentation

◆ _alloc()

ident _alloc ( Class clazz)

Instantiate a type through the given Class.

Definition at line 123 of file Class.c.

123 {
124
125 ident obj = calloc(1, clazz->def.instanceSize);
126 assert(obj);
127
128 Object *object = (Object *) obj;
129
130 object->magic = OBJECTIVELY_MAGIC;
131 object->clazz = clazz;
132 object->referenceCount = 1;
133
134 ident interface = clazz->interface;
135 do {
136 *(ident *) (obj + clazz->def.interfaceOffset) = interface;
137 } while ((clazz = clazz->def.superclass));
138
139 return obj;
140}
#define obj
#define OBJECTIVELY_MAGIC
The header value identifying Objectively types.
Definition Class.h:159
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49
size_t instanceSize
The instance size (required).
Definition Class.h:69
ptrdiff_t interfaceOffset
The interface offset (required).
Definition Class.h:74
Class * superclass
The superclass (required). e.g. _Object().
Definition Class.h:89
ClassDef def
The Class definition.
Definition Class.h:100
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46
unsigned int magic
A header to allow introspection of Object types.
Definition Object.h:50

◆ _cast()

ident _cast ( const Class clazz,
const ident  obj 
)

Perform a type-checking cast.

Definition at line 142 of file Class.c.

142 {
143
144 if (obj) {
145 const Class *c = ((Object *) obj)->clazz;
146 while (c) {
147
148 // as a special case, we optimize for _Object
149 if (c == clazz || clazz == _Object()) {
150 break;
151 }
152
153 c = c->def.superclass;
154 }
155 assert(c);
156 }
157
158 return (ident) obj;
159}
Class * _Object(void)
Definition Object.c:136
The runtime representation of a Class.
Definition Class.h:95

◆ _initialize()

Class * _initialize ( const ClassDef clazz)

Initializes the given Class.

Parameters
clazzThe Class descriptor.
Returns
The initialized Class.

Definition at line 86 of file Class.c.

86 {
87
88 static Once once;
89 do_once(&once, setup());
90
91 assert(def);
92 assert(def->name);
93 assert(def->instanceSize);
94 assert(def->interfaceSize);
95 assert(def->interfaceOffset);
96
97 Class *clazz = calloc(1, sizeof(Class));
98 assert(clazz);
99
100 clazz->def = *def;
101
102 clazz->interface = calloc(1, def->interfaceSize);
103 assert(clazz->interface);
104
105 Class *superclass = clazz->def.superclass;
106 if (superclass) {
107
108 assert(superclass->def.instanceSize <= def->instanceSize);
109 assert(superclass->def.interfaceSize <= def->interfaceSize);
110
111 memcpy(clazz->interface, superclass->interface, superclass->def.interfaceSize);
112 }
113
114 if (clazz->def.initialize) {
115 clazz->def.initialize(clazz);
116 }
117
118 clazz->next = __sync_lock_test_and_set(&_classes, clazz);
119
120 return clazz;
121}
static void setup(void)
Called when initializing Object to setup Objectively.
Definition Class.c:73
static Class * _classes
Definition Class.c:41
long Once
The Once type.
Definition Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition Once.h:43
size_t interfaceSize
The interface size (required).
Definition Class.h:79
const char * name
The Class name (required).
Definition Class.h:84
void(* initialize)(Class *clazz)
The Class initializer (optional).
Definition Class.h:64
Class * next
Provides chaining of initialized Classes.
Definition Class.h:110
ident interface
The interface of the Class.
Definition Class.h:105

◆ classForName()

Class * classForName ( const char *  name)
Returns
The Class with the given name, or NULL if no such Class has been initialized.

Definition at line 161 of file Class.c.

161 {
162
163 if (name) {
164 Class *c = _classes;
165 while (c) {
166 if (strcmp(name, c->def.name) == 0) {
167 return c;
168 }
169 c = c->next;
170 }
171
172 char *s;
173 if (asprintf(&s, "_%s", name) > 0) {
174 Class *clazz = NULL;
175#if defined(_WIN32)
176 static Once once;
177 static ident handle;
178 do_once(&once, { handle = dlopen(NULL, RTLD_LAZY); });
179 Class *(*archetype)(void) = handle ? dlsym(handle, s) : NULL;
180#else
181 Class *(*archetype)(void) = dlsym(RTLD_DEFAULT, s);
182#endif
183 if (archetype) {
184 clazz = archetype();
185 }
186
187 free(s);
188 return clazz;
189 }
190 }
191
192 return NULL;
193}

◆ release()

ident release ( ident  obj)

Atomically decrement the given Object's reference count. If the resulting reference count is 0, the Object is deallocated.

Returns
This function always returns NULL.

Definition at line 195 of file Class.c.

195 {
196
197 if (obj) {
198 Object *object = cast(Object, obj);
199
200 assert(object);
201
202 if (__sync_add_and_fetch(&object->referenceCount, -1) == 0) {
203 $(object, dealloc);
204 }
205 }
206
207 return NULL;
208}
static void dealloc(Object *self)
Definition Array.c:99
#define cast(type, obj)
Safely cast obj to type.
Definition Class.h:182

◆ retain()

ident retain ( ident  obj)

Atomically increment the given Object's reference count.

Returns
The Object.
Remarks
By calling this, the caller is expressing ownership of the Object, and preventing it from being released. Be sure to balance calls to retain with calls to release.

Definition at line 210 of file Class.c.

210 {
211
212 Object *object = cast(Object, obj);
213
214 assert(object);
215
216 __sync_add_and_fetch(&object->referenceCount, 1);
217
218 return obj;
219}

◆ setup()

static void setup ( void  )
static

Called when initializing Object to setup Objectively.

Definition at line 73 of file Class.c.

73 {
74
75 _classes = NULL;
76
77#if !defined(_SC_PAGESIZE)
78 _pageSize = 4096;
79#else
80 _pageSize = sysconf(_SC_PAGESIZE);
81#endif
82
83 atexit(teardown);
84}
static void teardown(void)
Called atexit to teardown Objectively.
Definition Class.c:46
size_t _pageSize
Definition Class.c:39

◆ teardown()

static void teardown ( void  )
static

Called atexit to teardown Objectively.

Definition at line 46 of file Class.c.

46 {
47 Class *c;
48
49 c = _classes;
50 while (c) {
51 if (c->def.destroy) {
52 c->def.destroy(c);
53 }
54
55 c = c->next;
56 }
57
58 c = _classes;
59 while (c) {
60
61 Class *next = c->next;
62
63 free(c->interface);
64 free(c);
65
66 c = next;
67 }
68}
static Unicode next(StringReader *self, StringReaderMode mode)
void(* destroy)(Class *clazz)
The Class destructor (optional). This method is run for initialized Classes when your application exi...
Definition Class.h:47

Variable Documentation

◆ _classes

Class* _classes
static

Definition at line 41 of file Class.c.

◆ _pageSize

size_t _pageSize

Definition at line 39 of file Class.c.