/*
docCopyright("Steve Dekorte", 2002)
docLicense("BSD revised")
*/
#ifdef IOOBJECT_C
#define IO_IN_C_FILE
#endif
#include "Common_inline.h"
#ifdef IO_DECLARE_INLINES
#include "IoVMApi.h"
#include "IoState.h"
IOINLINE int IoObject_isWhite(IoObject *self)
{
return Collector_markerIsWhite_(IOCOLLECTOR, &(self->marker));
}
IOINLINE int IoObject_isGray(IoObject *self)
{
return Collector_markerIsGray_(IOCOLLECTOR, &(self->marker));
}
IOINLINE int IoObject_isBlack(IoObject *self)
{
return Collector_markerIsBlack_(IOCOLLECTOR, &(self->marker));
}
IOINLINE void IoObject_createSlotsIfNeeded(IoObject *self)
{
if (!self->ownsSlots)
{
/*printf("creating slots for %s %p\n", self->tag->name, (void *)self);*/
IoObject_createSlots(self);
}
}
IOINLINE void IoObject_rawRemoveAllProtos(IoObject *self)
{
IoObject_createSlotsIfNeeded(self);
{
int count = IoObject_rawProtosCount(self);
memset(self->protos, 0, count * sizeof(IoObject *));
}
}
IOINLINE void IoObject_shouldMark(IoObject *self)
{
Collector_shouldMark_(IOCOLLECTOR, self);
}
IOINLINE void IoObject_shouldMarkIfNonNull(IoObject *self)
{
if (self)
{
IoObject_shouldMark(self);
}
}
IOINLINE IoObject *IoObject_addingRef_(IoObject *self, IoObject *ref)
{
Collector_value_addingRefTo_(IOCOLLECTOR, self, ref);
//self->isDirty = 1;
return ref;
}
IOINLINE void IoObject_inlineSetSlot_to_(IoObject *self,
IoSymbol *slotName,
IoObject *value)
{
IoObject_createSlotsIfNeeded(self);
/*
if (!slotName->isSymbol)
{
printf("Io System Error: setSlot slotName not symbol\n");
exit(1);
}
*/
/*
if (PHash_count(self->slots) > 200)
{
printf("PHash %p slots %i\n", (void *)(self->slots), PHash_count(self->slots));
IoState_error_(IOSTATE, NULL, "too many slots");
}
*/
PHash_at_put_(self->slots, IOREF(slotName), IOREF(value));
/*
if(PHash_at_put_(self->slots, IOREF(slotName), IOREF(value)))
{
self->isDirty = 1;
}
*/
}
IOINLINE IoObject *IoObject_rawGetSlot_context_(IoObject *self,
IoSymbol *slotName,
IoObject **context)
{
register IoObject *v = (IoObject *)NULL;
if (self->ownsSlots)
{
v = (IoObject *)PHash_at_(self->slots, slotName);
if (v)
{
*context = self;
return v;
}
}
IoObject_setHasDoneLookup_(self, 1);
{
register IoObject **protos = self->protos;
for (; *protos; protos ++)
{
if (IoObject_hasDoneLookup((*protos)))
{
continue;
}
v = IoObject_rawGetSlot_context_(*protos, slotName, context);
if (v)
{
break;
}
}
}
IoObject_setHasDoneLookup_(self, 0);
return v;
}
IOINLINE IoObject *IoObject_rawGetSlot_(IoObject *self, IoSymbol *slotName)
{
register IoObject *v = (IoObject *)NULL;
if (self->ownsSlots)
{
v = (IoObject *)PHash_at_(self->slots, slotName);
if (v) return v;
}
IoObject_setHasDoneLookup_(self, 1);
{
register IoObject **protos = self->protos;
for (; *protos; protos ++)
{
if (IoObject_hasDoneLookup((*protos)))
{
continue;
}
v = IoObject_rawGetSlot_(*protos, slotName);
if (v) break;
}
}
IoObject_setHasDoneLookup_(self, 0);
return v;
}
IOINLINE IoObject *IoObject_firstProto(IoObject *self)
{
return self->protos[0];
}
IOINLINE IoObject *IoObject_rawProtoAt_(IoObject *self, int i)
{
return self->protos[i];
}
IOINLINE void IoObject_mark(IoObject *self)
{
/*
if (self->isLocals)
{
printf("mark %p locals\n", (void *)self);
}
else
{
printf("mark %p %s\n", (void *)self, IoObject_name(self));
}
*/
if (self->ownsSlots)
{
PHash_doOnKeyAndValue_(self->slots, (PHashDoCallback *)IoObject_shouldMark);
}
// mark protos
{
IoObject **proto = self->protos;
while (*proto != NULL)
{
IoObject_shouldMark(*proto);
proto ++;
}
}
{
TagMarkFunc *func = self->tag->markFunc;
if (func)
{
(func)(self);
}
}
}
IoObject *IoObject_addingRef_(IoObject *self, IoObject *ref);
IOVM_API int IoObject_hasCloneFunc_(IoObject *self, TagCloneFunc *func);
IOINLINE IoObject *IoObject_activate(IoObject *self,
IoObject *target,
IoObject *locals,
IoMessage *m,
IoObject *slotContext)
{
//TagActivateFunc *act = self->tag->activateFunc;
//return act ? (IoObject *)((*act)(self, target, locals, m, slotContext)) : self;
//printf("activate %s %i\n", self->tag->name, self->isActivatable);
return self->isActivatable ? (IoObject *)((self->tag->activateFunc)(self, target, locals, m, slotContext)) : self;
//return self->tag->activateFunc ? (IoObject *)((self->tag->activateFunc)(self, target, locals, m, slotContext)) : self;
}
IOINLINE IoObject *IoObject_forward(IoObject *self, IoObject *locals, IoMessage *m)
{
IoState *state = IOSTATE;
IoObject *context;
IoObject *forwardSlot = IoObject_rawGetSlot_context_(self, state->forwardSymbol, &context);
if (Coro_stackSpaceAlmostGone((Coro*)IoCoroutine_cid(state->currentCoroutine)))
{
IoState_error_(IOSTATE, m, "stack overflow in forward while sending '%s' message to a '%s' object",
CSTRING(IoMessage_name(m)), IoObject_name(self));
}
if (forwardSlot)
{
return IoObject_activate(forwardSlot, self, locals, m, context);
}
IoState_error_(state, m, "'%s' does not respond to message '%s'",
IoObject_name(self), CSTRING(IoMessage_name(m)));
return self;
}
IOINLINE IoObject *IoObject_perform(IoObject *self, IoObject *locals, IoMessage *m)
{
IoObject *context;
IoObject *slotValue = IoObject_rawGetSlot_context_(self, IoMessage_name(m), &context);
// note: coro chaining was moved to IoBlock.c
if (slotValue)
{
return IoObject_activate(slotValue, self, locals, m, context);
}
if (self->isLocals)
{
return IoObject_localsForward(self, locals, m);
}
return IoObject_forward(self, locals, m);
}
#undef IO_IN_C_FILE
#endif
syntax highlighted by Code2HTML, v. 0.9.1