Fixed a lazySlot bug where lazy slots in different objects end up pointing to the...
[io/quag.git] / libs / iovm / source / IoObject_inline.h
blobc6bc68b7793159be89ca42a8153d18dd3dccdb45
1 /*
2 docCopyright("Steve Dekorte", 2002)
3 docLicense("BSD revised")
4 */
6 #ifdef IOOBJECT_C
7 #define IO_IN_C_FILE
8 #endif
9 #include "Common_inline.h"
10 #ifdef IO_DECLARE_INLINES
12 #include "IoVMApi.h"
13 #include "IoState.h"
15 #define IOOBJECT_FOREACHPROTO(self, pvar, code) \
17 IoObject **_proto = IoObject_protos(self); \
18 while (*_proto) \
19 { \
20 IoObject *pvar = *_proto; \
21 code; \
22 _proto++; \
23 } \
27 IOINLINE PHash *IoObject_slots(IoObject *self)
29 IoObjectData *od = IoObject_deref(self);
30 return od->slots;
33 IOINLINE void IoObject_slots_(IoObject *self, PHash *v)
35 IoObjectData *od = IoObject_deref(self);
36 od->slots = v;
39 IOINLINE IoObject **IoObject_protos(IoObject *self)
41 IoObjectData *od = IoObject_deref(self);
42 return od->protos;
45 IOINLINE void IoObject_protos_(IoObject *self, IoObject **v)
47 IoObjectData *od = IoObject_deref(self);
48 od->protos = v;
53 IOINLINE int IoObject_isWhite(IoObject *self)
55 return Collector_markerIsWhite_(IOCOLLECTOR, (CollectorMarker *)self);
58 IOINLINE int IoObject_isGray(IoObject *self)
60 return Collector_markerIsGray_(IOCOLLECTOR, (CollectorMarker *)self);
63 IOINLINE int IoObject_isBlack(IoObject *self)
65 return Collector_markerIsBlack_(IOCOLLECTOR, (CollectorMarker *)self);
69 IOINLINE void IoObject_createSlotsIfNeeded(IoObject *self)
71 if (!IoObject_ownsSlots(self))
73 /*printf("creating slots for %s %p\n", IoObject_tag(self)->name, (void *)self);*/
74 IoObject_createSlots(self);
78 IOINLINE void IoObject_rawRemoveAllProtos(IoObject *self)
80 //IoObject_createSlotsIfNeeded(self);
81 memset(IoObject_protos(self), 0, IoObject_rawProtosCount(self) * sizeof(IoObject *));
84 IOINLINE void IoObject_shouldMark(IoObject *self)
86 Collector_shouldMark_(IOCOLLECTOR, self);
89 IOINLINE void IoObject_shouldMarkIfNonNull(IoObject *self)
91 if (self)
93 IoObject_shouldMark(self);
97 IOINLINE void IoObject_freeIfUnreferenced(IoObject *self)
99 if (!IoObject_isReferenced(self) && !Collector_isPaused(IOSTATE->collector))
101 CollectorMarker_remove((CollectorMarker *)self);
102 IoObject_free(self);
106 IOINLINE IoObject *IoObject_addingRef_(IoObject *self, IoObject *ref)
108 #ifdef IO_BLOCK_LOCALS_RECYCLING
109 //printf("IoObject_addingRef_\n");
110 if(IoObject_isLocals(self))
112 //printf("IoObject_isReferenced_\n");
113 IoObject_isReferenced_(ref, 1);
115 #endif
117 Collector_value_addingRefTo_(IOCOLLECTOR, self, ref);
118 //IoObject_isDirty_(self, 1);
120 return ref;
123 IOINLINE void IoObject_inlineSetSlot_to_(IoObject *self,
124 IoSymbol *slotName,
125 IoObject *value)
127 IoObject_createSlotsIfNeeded(self);
129 if (!slotName->isSymbol)
131 printf("Io System Error: setSlot slotName not symbol\n");
132 exit(1);
136 PHash_at_put_(IoObject_slots(self), IOREF(slotName), IOREF(value));
139 if(PHash_at_put_(IoObject_slots(self), IOREF(slotName), IOREF(value)))
141 IoObject_isDirty_(self, 1);
146 IOINLINE IoObject *IoObject_rawGetSlot_context_(IoObject *self,
147 IoSymbol *slotName,
148 IoObject **context)
150 register IoObject *v = (IoObject *)NULL;
152 if (IoObject_ownsSlots(self))
154 v = (IoObject *)PHash_at_(IoObject_slots(self), slotName);
156 if (v)
158 *context = self;
159 return v;
163 IoObject_hasDoneLookup_(self, 1);
166 register IoObject **protos = IoObject_protos(self);
168 for (; *protos; protos ++)
170 if (IoObject_hasDoneLookup((*protos)))
172 continue;
175 v = IoObject_rawGetSlot_context_(*protos, slotName, context);
177 if (v)
179 break;
184 IoObject_hasDoneLookup_(self, 0);
186 return v;
189 IOINLINE IoObject *IoObject_rawGetSlot_(IoObject *self, IoSymbol *slotName)
191 register IoObject *v = (IoObject *)NULL;
193 if (IoObject_ownsSlots(self))
195 v = (IoObject *)PHash_at_(IoObject_slots(self), slotName);
197 if (v) return v;
200 IoObject_hasDoneLookup_(self, 1);
203 register IoObject **protos = IoObject_protos(self);
205 for (; *protos; protos ++)
207 if (IoObject_hasDoneLookup((*protos)))
209 continue;
212 v = IoObject_rawGetSlot_(*protos, slotName);
214 if (v) break;
218 IoObject_hasDoneLookup_(self, 0);
220 return v;
223 IOINLINE int IoObject_mark(IoObject *self)
226 if (IoObject_isLocals(self))
228 printf("mark %p locals\n", (void *)self);
230 else
232 printf("mark %p %s\n", (void *)self, IoObject_name(self));
236 if (IoObject_ownsSlots(self))
238 PHASH_FOREACH(IoObject_slots(self), k, v,
239 IoObject_shouldMark((IoObject *)k);
240 IoObject_shouldMark((IoObject *)v);
244 // mark protos
246 IOOBJECT_FOREACHPROTO(self, proto, IoObject_shouldMark(proto));
249 IoTagMarkFunc *func = IoTag_markFunc(IoObject_tag(self));
251 if (func)
253 (func)(self);
257 return 1;
260 IoObject *IoObject_addingRef_(IoObject *self, IoObject *ref);
261 IOVM_API int IoObject_hasCloneFunc_(IoObject *self, IoTagCloneFunc *func);
263 IOINLINE IoObject *IoObject_activate(IoObject *self,
264 IoObject *target,
265 IoObject *locals,
266 IoMessage *m,
267 IoObject *slotContext)
269 //TagActivateFunc *act = IoObject_tag(self)->activateFunc;
270 //return act ? (IoObject *)((*act)(self, target, locals, m, slotContext)) : self;
271 //printf("activate %s %i\n", IoObject_tag(self)->name, IoObject_isActivatable(self));
273 return IoObject_isActivatable(self) ? (IoObject *)((IoObject_tag(self)->activateFunc)(self, target, locals, m, slotContext)) : self;
274 //return IoObject_tag(self)->activateFunc ? (IoObject *)((IoObject_tag(self)->activateFunc)(self, target, locals, m, slotContext)) : self;
277 IOINLINE IoObject *IoObject_forward(IoObject *self, IoObject *locals, IoMessage *m)
279 IoState *state = IOSTATE;
280 IoObject *context;
281 IoObject *forwardSlot = IoObject_rawGetSlot_context_(self, state->forwardSymbol, &context);
284 if (Coro_stackSpaceAlmostGone((Coro*)IoCoroutine_cid(state->currentCoroutine)))
287 IoState_error_(IOSTATE, m, "stack overflow in forward while sending '%s' message to a '%s' object",
288 CSTRING(IoMessage_name(m)), IoObject_name(self));
292 if (forwardSlot)
294 return IoObject_activate(forwardSlot, self, locals, m, context);
297 IoState_error_(state, m, "'%s' does not respond to message '%s'",
298 IoObject_name(self), CSTRING(IoMessage_name(m)));
299 return self;
302 IOINLINE IoObject *IoObject_perform(IoObject *self, IoObject *locals, IoMessage *m)
304 IoObject *context;
305 IoObject *slotValue = IoObject_rawGetSlot_context_(self, IoMessage_name(m), &context);
307 // note: coro chaining was moved to IoBlock.c
309 if (slotValue)
311 return IoObject_activate(slotValue, self, locals, m, context);
314 if (IoObject_isLocals(self))
316 return IoObject_localsForward(self, locals, m);
319 return IoObject_forward(self, locals, m);
322 #undef IO_IN_C_FILE
323 #endif