Objectively 1.0.0
Ultra-lightweight object oriented framework for GNU C.
Functions | Variables
Class.c File Reference
#include "Config.h"
#include <assert.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.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. More...
 
ident _cast (Class *clazz, const ident obj)
 Perform a type-checking cast. More...
 
Class_initialize (const ClassDef *def)
 Initializes the given Class. More...
 
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. More...
 
ident retain (ident obj)
 Atomically increment the given Object's reference count. More...
 
static void setup (void)
 Called when initializing Object to setup Objectively. More...
 
static void teardown (void)
 Called atexit to teardown Objectively. More...
 

Variables

static Class_classes
 
static ident _handle
 
size_t _pageSize
 

Function Documentation

◆ _alloc()

ident _alloc ( Class clazz)

Instantiate a type through the given Class.

Definition at line 128 of file Class.c.

128 {
129
130 ident obj = calloc(1, clazz->def.instanceSize);
131 assert(obj);
132
133 Object *object = (Object *) obj;
134
135 object->clazz = clazz;
136 object->referenceCount = 1;
137
138 ident interface = clazz->interface;
139 do {
140 *(ident *) (obj + clazz->def.interfaceOffset) = interface;
141 } while ((clazz = clazz->def.superclass));
142
143 return obj;
144}
#define obj
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

◆ _cast()

ident _cast ( Class clazz,
const ident  obj 
)

Perform a type-checking cast.

Definition at line 146 of file Class.c.

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

◆ _initialize()

Class * _initialize ( const ClassDef clazz)

Initializes the given Class.

Parameters
clazzThe Class descriptor.
Returns
The initialized Class.

Definition at line 91 of file Class.c.

91 {
92
93 static Once once;
94 do_once(&once, setup());
95
96 assert(def);
97 assert(def->name);
98 assert(def->instanceSize);
99 assert(def->interfaceSize);
100 assert(def->interfaceOffset);
101
102 Class *clazz = calloc(1, sizeof(Class));
103 assert(clazz);
104
105 clazz->def = *def;
106
107 clazz->interface = calloc(1, def->interfaceSize);
108 assert(clazz->interface);
109
110 Class *superclass = clazz->def.superclass;
111 if (superclass) {
112
113 assert(superclass->def.instanceSize <= def->instanceSize);
114 assert(superclass->def.interfaceSize <= def->interfaceSize);
115
116 memcpy(clazz->interface, superclass->interface, superclass->def.interfaceSize);
117 }
118
119 if (clazz->def.initialize) {
120 clazz->def.initialize(clazz);
121 }
122
123 clazz->next = __sync_lock_test_and_set(&_classes, clazz);
124
125 return clazz;
126}
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
void setup(URLSessionTask *)
Sets up this task.

◆ 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 165 of file Class.c.

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

◆ 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 196 of file Class.c.

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

◆ 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 211 of file Class.c.

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

◆ setup()

static void setup ( void  )
static

Called when initializing Object to setup Objectively.

Definition at line 78 of file Class.c.

78 {
79
80 _classes = NULL;
81
82#if !defined(_SC_PAGESIZE)
83 _pageSize = 4096;
84#else
85 _pageSize = sysconf(_SC_PAGESIZE);
86#endif
87
88 atexit(teardown);
89}
size_t _pageSize
Definition: Class.c:39
void teardown(URLSessionTask *)
Tears down this task.

◆ teardown()

static void teardown ( void  )
static

Called atexit to teardown Objectively.

Definition at line 47 of file Class.c.

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

Variable Documentation

◆ _classes

Class* _classes
static

Definition at line 41 of file Class.c.

◆ _handle

ident _handle
static

Definition at line 42 of file Class.c.

◆ _pageSize

size_t _pageSize

Definition at line 39 of file Class.c.