New doc system done for core
[io.git] / libs / iovm / source / IoObject_inline.h
blobb3545226d25759815a0a91b2af1f7b7c857edc47
2 //metadoc Object copyright Steve Dekorte 2002
3 //metadoc Object license BSD revised
5 #ifdef IOOBJECT_C
6 #define IO_IN_C_FILE
7 #endif
8 #include "Common_inline.h"
9 #ifdef IO_DECLARE_INLINES
11 #include "IoVMApi.h"
12 #include "IoState.h"
14 #define IOOBJECT_FOREACHPROTO(self, pvar, code) \
16 IoObject **_proto = IoObject_protos(self); \
17 while (*_proto) \
18 { \
19 IoObject *pvar = *_proto; \
20 code; \
21 _proto++; \
22 } \
26 IOINLINE PHash *IoObject_slots(IoObject *self)
28 IoObjectData *od = IoObject_deref(self);
29 return od->slots;
32 IOINLINE void IoObject_slots_(IoObject *self, PHash *v)
34 IoObjectData *od = IoObject_deref(self);
35 od->slots = v;
38 IOINLINE IoObject **IoObject_protos(IoObject *self)
40 IoObjectData *od = IoObject_deref(self);
41 return od->protos;
44 IOINLINE void IoObject_protos_(IoObject *self, IoObject **v)
46 IoObjectData *od = IoObject_deref(self);
47 od->protos = v;
52 IOINLINE int IoObject_isWhite(IoObject *self)
54 return Collector_markerIsWhite_(IOCOLLECTOR, (CollectorMarker *)self);
57 IOINLINE int IoObject_isGray(IoObject *self)
59 return Collector_markerIsGray_(IOCOLLECTOR, (CollectorMarker *)self);
62 IOINLINE int IoObject_isBlack(IoObject *self)
64 return Collector_markerIsBlack_(IOCOLLECTOR, (CollectorMarker *)self);
68 IOINLINE void IoObject_createSlotsIfNeeded(IoObject *self)
70 if (!IoObject_ownsSlots(self))
72 /*printf("creating slots for %s %p\n", IoObject_tag(self)->name, (void *)self);*/
73 IoObject_createSlots(self);
77 IOINLINE void IoObject_rawRemoveAllProtos(IoObject *self)
79 //IoObject_createSlotsIfNeeded(self);
80 memset(IoObject_protos(self), 0, IoObject_rawProtosCount(self) * sizeof(IoObject *));
83 IOINLINE void IoObject_shouldMark(IoObject *self)
85 Collector_shouldMark_(IOCOLLECTOR, self);
88 IOINLINE void IoObject_shouldMarkIfNonNull(IoObject *self)
90 if (self)
92 IoObject_shouldMark(self);
96 IOINLINE void IoObject_freeIfUnreferenced(IoObject *self)
98 if (!IoObject_isReferenced(self) && !Collector_isPaused(IOSTATE->collector))
100 CollectorMarker_remove((CollectorMarker *)self);
101 IoObject_free(self);
105 IOINLINE IoObject *IoObject_addingRef_(IoObject *self, IoObject *ref)
107 #ifdef IO_BLOCK_LOCALS_RECYCLING
108 //printf("IoObject_addingRef_\n");
109 if(IoObject_isLocals(self))
111 //printf("IoObject_isReferenced_\n");
112 IoObject_isReferenced_(ref, 1);
114 #endif
116 Collector_value_addingRefTo_(IOCOLLECTOR, self, ref);
117 //IoObject_isDirty_(self, 1);
119 return ref;
122 IOINLINE void IoObject_inlineSetSlot_to_(IoObject *self,
123 IoSymbol *slotName,
124 IoObject *value)
126 IoObject_createSlotsIfNeeded(self);
128 if (!slotName->isSymbol)
130 printf("Io System Error: setSlot slotName not symbol\n");
131 exit(1);
135 PHash_at_put_(IoObject_slots(self), IOREF(slotName), IOREF(value));
138 if(PHash_at_put_(IoObject_slots(self), IOREF(slotName), IOREF(value)))
140 IoObject_isDirty_(self, 1);
145 IOINLINE IoObject *IoObject_rawGetSlot_context_(IoObject *self,
146 IoSymbol *slotName,
147 IoObject **context)
149 register IoObject *v = (IoObject *)NULL;
151 if (IoObject_ownsSlots(self))
153 v = (IoObject *)PHash_at_(IoObject_slots(self), slotName);
155 if (v)
157 *context = self;
158 return v;
162 IoObject_hasDoneLookup_(self, 1);
165 register IoObject **protos = IoObject_protos(self);
167 for (; *protos; protos ++)
169 if (IoObject_hasDoneLookup((*protos)))
171 continue;
174 v = IoObject_rawGetSlot_context_(*protos, slotName, context);
176 if (v)
178 break;
183 IoObject_hasDoneLookup_(self, 0);
185 return v;
188 IOINLINE IoObject *IoObject_rawGetSlot_(IoObject *self, IoSymbol *slotName)
190 register IoObject *v = (IoObject *)NULL;
192 if (IoObject_ownsSlots(self))
194 v = (IoObject *)PHash_at_(IoObject_slots(self), slotName);
196 if (v) return v;
199 IoObject_hasDoneLookup_(self, 1);
202 register IoObject **protos = IoObject_protos(self);
204 for (; *protos; protos ++)
206 if (IoObject_hasDoneLookup((*protos)))
208 continue;
211 v = IoObject_rawGetSlot_(*protos, slotName);
213 if (v) break;
217 IoObject_hasDoneLookup_(self, 0);
219 return v;
222 IOINLINE int IoObject_mark(IoObject *self)
225 if (IoObject_isLocals(self))
227 printf("mark %p locals\n", (void *)self);
229 else
231 printf("mark %p %s\n", (void *)self, IoObject_name(self));
235 if (IoObject_ownsSlots(self))
237 PHASH_FOREACH(IoObject_slots(self), k, v,
238 IoObject_shouldMark((IoObject *)k);
239 IoObject_shouldMark((IoObject *)v);
243 // mark protos
245 IOOBJECT_FOREACHPROTO(self, proto, IoObject_shouldMark(proto));
248 IoTagMarkFunc *func = IoTag_markFunc(IoObject_tag(self));
250 if (func)
252 (func)(self);
256 return 1;
259 IoObject *IoObject_addingRef_(IoObject *self, IoObject *ref);
260 IOVM_API int IoObject_hasCloneFunc_(IoObject *self, IoTagCloneFunc *func);
262 IOINLINE IoObject *IoObject_activate(IoObject *self,
263 IoObject *target,
264 IoObject *locals,
265 IoMessage *m,
266 IoObject *slotContext)
268 //TagActivateFunc *act = IoObject_tag(self)->activateFunc;
269 //return act ? (IoObject *)((*act)(self, target, locals, m, slotContext)) : self;
270 //printf("activate %s %i\n", IoObject_tag(self)->name, IoObject_isActivatable(self));
272 return IoObject_isActivatable(self) ? (IoObject *)((IoObject_tag(self)->activateFunc)(self, target, locals, m, slotContext)) : self;
273 //return IoObject_tag(self)->activateFunc ? (IoObject *)((IoObject_tag(self)->activateFunc)(self, target, locals, m, slotContext)) : self;
276 IOINLINE IoObject *IoObject_forward(IoObject *self, IoObject *locals, IoMessage *m)
278 IoState *state = IOSTATE;
279 IoObject *context;
280 IoObject *forwardSlot = IoObject_rawGetSlot_context_(self, state->forwardSymbol, &context);
283 if (Coro_stackSpaceAlmostGone((Coro*)IoCoroutine_cid(state->currentCoroutine)))
286 IoState_error_(IOSTATE, m, "stack overflow in forward while sending '%s' message to a '%s' object",
287 CSTRING(IoMessage_name(m)), IoObject_name(self));
291 if (forwardSlot)
293 return IoObject_activate(forwardSlot, self, locals, m, context);
296 IoState_error_(state, m, "'%s' does not respond to message '%s'",
297 IoObject_name(self), CSTRING(IoMessage_name(m)));
298 return self;
301 IOINLINE IoObject *IoObject_perform(IoObject *self, IoObject *locals, IoMessage *m)
303 IoObject *context;
304 IoObject *slotValue = IoObject_rawGetSlot_context_(self, IoMessage_name(m), &context);
306 // note: coro chaining was moved to IoBlock.c
308 if (slotValue)
310 return IoObject_activate(slotValue, self, locals, m, context);
313 if (IoObject_isLocals(self))
315 return IoObject_localsForward(self, locals, m);
318 return IoObject_forward(self, locals, m);
321 #undef IO_IN_C_FILE
322 #endif