2 docCopyright("Steve Dekorte", 2002)
3 docLicense("BSD revised")
9 #include "Common_inline.h"
10 #ifdef IO_DECLARE_INLINES
15 #define IOOBJECT_FOREACHPROTO(self, pvar, code) \
17 IoObject **_proto = IoObject_protos(self); \
20 IoObject *pvar = *_proto; \
27 IOINLINE PHash *IoObject_slots(IoObject *self)
29 IoObjectData *od = IoObject_deref(self);
33 IOINLINE void IoObject_slots_(IoObject *self, PHash *v)
35 IoObjectData *od = IoObject_deref(self);
39 IOINLINE IoObject **IoObject_protos(IoObject *self)
41 IoObjectData *od = IoObject_deref(self);
45 IOINLINE void IoObject_protos_(IoObject *self, IoObject **v)
47 IoObjectData *od = IoObject_deref(self);
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
)
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
);
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);
117 Collector_value_addingRefTo_(IOCOLLECTOR
, self
, ref
);
118 //IoObject_isDirty_(self, 1);
123 IOINLINE
void IoObject_inlineSetSlot_to_(IoObject
*self
,
127 IoObject_createSlotsIfNeeded(self
);
129 if (!slotName->isSymbol)
131 printf("Io System Error: setSlot slotName not symbol\n");
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
,
150 register IoObject
*v
= (IoObject
*)NULL
;
152 if (IoObject_ownsSlots(self
))
154 v
= (IoObject
*)PHash_at_(IoObject_slots(self
), slotName
);
163 IoObject_hasDoneLookup_(self
, 1);
166 register IoObject
**protos
= IoObject_protos(self
);
168 for (; *protos
; protos
++)
170 if (IoObject_hasDoneLookup((*protos
)))
175 v
= IoObject_rawGetSlot_context_(*protos
, slotName
, context
);
184 IoObject_hasDoneLookup_(self
, 0);
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
);
200 IoObject_hasDoneLookup_(self
, 1);
203 register IoObject
**protos
= IoObject_protos(self
);
205 for (; *protos
; protos
++)
207 if (IoObject_hasDoneLookup((*protos
)))
212 v
= IoObject_rawGetSlot_(*protos
, slotName
);
218 IoObject_hasDoneLookup_(self
, 0);
223 IOINLINE
int IoObject_mark(IoObject
*self
)
226 if (IoObject_isLocals(self))
228 printf("mark %p locals\n", (void *)self);
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
);
246 IOOBJECT_FOREACHPROTO(self
, proto
, IoObject_shouldMark(proto
));
249 IoTagMarkFunc
*func
= IoTag_markFunc(IoObject_tag(self
));
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
,
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
;
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));
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
)));
302 IOINLINE IoObject
*IoObject_perform(IoObject
*self
, IoObject
*locals
, IoMessage
*m
)
305 IoObject
*slotValue
= IoObject_rawGetSlot_context_(self
, IoMessage_name(m
), &context
);
307 // note: coro chaining was moved to IoBlock.c
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
);