2 //metadoc Object copyright Steve Dekorte 2002
3 //metadoc Object license BSD revised
8 #include "Common_inline.h"
9 #ifdef IO_DECLARE_INLINES
14 #define IOOBJECT_FOREACHPROTO(self, pvar, code) \
16 IoObject **_proto = IoObject_protos(self); \
19 IoObject *pvar = *_proto; \
26 IOINLINE PHash *IoObject_slots(IoObject *self)
28 IoObjectData *od = IoObject_deref(self);
32 IOINLINE void IoObject_slots_(IoObject *self, PHash *v)
34 IoObjectData *od = IoObject_deref(self);
38 IOINLINE IoObject **IoObject_protos(IoObject *self)
40 IoObjectData *od = IoObject_deref(self);
44 IOINLINE void IoObject_protos_(IoObject *self, IoObject **v)
46 IoObjectData *od = IoObject_deref(self);
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
)
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
);
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);
116 Collector_value_addingRefTo_(IOCOLLECTOR
, self
, ref
);
117 //IoObject_isDirty_(self, 1);
122 IOINLINE
void IoObject_inlineSetSlot_to_(IoObject
*self
,
126 IoObject_createSlotsIfNeeded(self
);
128 if (!slotName->isSymbol)
130 printf("Io System Error: setSlot slotName not symbol\n");
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
,
149 register IoObject
*v
= (IoObject
*)NULL
;
151 if (IoObject_ownsSlots(self
))
153 v
= (IoObject
*)PHash_at_(IoObject_slots(self
), slotName
);
162 IoObject_hasDoneLookup_(self
, 1);
165 register IoObject
**protos
= IoObject_protos(self
);
167 for (; *protos
; protos
++)
169 if (IoObject_hasDoneLookup((*protos
)))
174 v
= IoObject_rawGetSlot_context_(*protos
, slotName
, context
);
183 IoObject_hasDoneLookup_(self
, 0);
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
);
199 IoObject_hasDoneLookup_(self
, 1);
202 register IoObject
**protos
= IoObject_protos(self
);
204 for (; *protos
; protos
++)
206 if (IoObject_hasDoneLookup((*protos
)))
211 v
= IoObject_rawGetSlot_(*protos
, slotName
);
217 IoObject_hasDoneLookup_(self
, 0);
222 IOINLINE
int IoObject_mark(IoObject
*self
)
225 if (IoObject_isLocals(self))
227 printf("mark %p locals\n", (void *)self);
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
);
245 IOOBJECT_FOREACHPROTO(self
, proto
, IoObject_shouldMark(proto
));
248 IoTagMarkFunc
*func
= IoTag_markFunc(IoObject_tag(self
));
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
,
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
;
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));
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
)));
301 IOINLINE IoObject
*IoObject_perform(IoObject
*self
, IoObject
*locals
, IoMessage
*m
)
304 IoObject
*slotValue
= IoObject_rawGetSlot_context_(self
, IoMessage_name(m
), &context
);
306 // note: coro chaining was moved to IoBlock.c
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
);