New doc system done for core
[io.git] / libs / iovm / source / IoCFunction.c
blob60d4d334a53c95dd12a9304c1f4cfaebb12111e6
1 //metadoc CFunction copyright Steve Dekorte 2002
2 //metadoc CFunction license BSD revised
3 /*metadoc CFunction description
4 A container for a pointer to a C function binding.
5 CFunction's can only be defined from the C side and act
6 like blocks in that when placed in a slot, are called when the
7 slot is activated. The for, if, while and clone methods of the Lobby
8 are examples of CFunctions. CFunctions are useful for implementing
9 methods that require the speed of C or binding to a C library.
11 //metadoc CFunction category Core")
13 #include "IoCFunction.h"
15 #include "IoState.h"
16 #include "IoNumber.h"
17 #include <stddef.h>
19 #define DATA(self) ((IoCFunctionData *)IoObject_dataPointer(self))
21 IoTag *IoCFunction_newTag(void *state)
23 IoTag *tag = IoTag_newWithName_("CFunction");
24 IoTag_state_(tag, state);
25 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoCFunction_rawClone);
26 IoTag_markFunc_(tag, (IoTagMarkFunc *)IoCFunction_mark);
27 IoTag_activateFunc_(tag, (IoTagActivateFunc *)IoCFunction_activate);
28 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoCFunction_free);
29 return tag;
32 IoCFunction *IoCFunction_proto(void *state)
34 IoObject *self = IoObject_new(state);
35 IoObject_tag_(self, IoCFunction_newTag(state));
37 IoObject_setDataPointer_(self, io_calloc(1, sizeof(IoCFunctionData)));
38 DATA(self)->func = IoObject_self;
39 //IoObject_isActivatable_(self, 1);
40 IoState_registerProtoWithFunc_((IoState *)state, self, IoCFunction_proto);
41 return self;
44 void IoCFunction_protoFinish(void *state)
46 IoMethodTable methodTable[] = {
47 {"id", IoCFunction_id},
48 {"==", IoCFunction_equals},
49 {"performOn", IoCFunction_performOn},
50 {"uniqueName", IoCFunction_uniqueName},
51 {"typeName", IoCFunction_typeName},
52 {NULL, NULL},
55 IoObject *self = IoState_protoWithInitFunction_((IoState *)state, IoCFunction_proto);
56 IoObject_setSlot_to_(self, IOSYMBOL("type"), IOSYMBOL("CFunction"));
57 /*doc CFunction type
58 Returns "Cfunction".
60 IoObject_addMethodTable_(self, methodTable);
63 IoCFunction *IoCFunction_rawClone(IoCFunction *proto)
65 IoObject *self = IoObject_rawClonePrimitive(proto);
66 IoObject_setDataPointer_(self, cpalloc(DATA(proto), sizeof(IoCFunctionData)));
67 IoObject_isActivatable_(self, 1);
68 return self;
71 void IoCFunction_mark(IoCFunction *self)
73 if (DATA(self)->uniqueName)
75 IoObject_shouldMark(DATA(self)->uniqueName);
79 void IoCFunction_free(IoCFunction *self)
81 io_free(IoObject_dataPointer(self));
84 void IoCFunction_print(IoCFunction *self)
86 IoCFunctionData *data = DATA(self);
88 printf("CFunction_%p", self);
89 printf(" %p", (data->func));
90 printf(" %s", data->typeTag ? data->typeTag->name : "?");
91 if (data->uniqueName) printf(" %s", CSTRING(data->uniqueName));
92 printf("\n");
95 IoCFunction *IoCFunction_newWithFunctionPointer_tag_name_(void *state,
96 IoUserFunction *func,
97 IoTag *typeTag,
98 const char *funcName)
100 IoCFunction *proto = IoState_protoWithInitFunction_((IoState *)state, IoCFunction_proto);
101 IoCFunction *self = IOCLONE(proto);
102 DATA(self)->typeTag = typeTag;
103 DATA(self)->func = func;
104 DATA(self)->uniqueName = IoState_symbolWithCString_((IoState *)state, funcName);
105 return self;
108 IoObject *IoCFunction_id(IoCFunction *self, IoObject *locals, IoMessage *m)
110 /*doc CFunction id
111 Returns a number containing a unique id for the receiver's internal C function.
114 return IONUMBER(((uintptr_t)self));
117 IoObject *IoCFunction_uniqueName(IoCFunction *self, IoObject *locals, IoMessage *m)
119 /*doc CFunction uniqueName
120 Returns the name given to the CFunction.
123 if (DATA(self)->uniqueName)
125 return DATA(self)->uniqueName;
128 return IONIL(self);
131 IoObject *IoCFunction_typeName(IoCFunction *self, IoObject *locals, IoMessage *m)
133 /*doc CFunction typeName
134 Returns the owning type of the CFunction or nil if the CFunction can be called on any object.
137 if (DATA(self)->typeTag)
139 return IOSYMBOL(IoTag_name(DATA(self)->typeTag));
142 return IONIL(self);
145 IoObject *IoCFunction_equals(IoCFunction *self, IoObject *locals, IoMessage *m)
147 /*doc CFunction ==(anObject)
148 Returns self if the argument is a CFunction with the same internal C function pointer.
151 IoObject *v = IoMessage_locals_valueArgAt_(m, locals, 0);
153 return IOBOOL(self, ISCFUNCTION(v) && (DATA(self)->func == DATA(v)->func));
156 IoObject *IoCFunction_activate(IoCFunction *self, IoObject *target, IoObject *locals, IoMessage *m, IoObject *slotContext)
158 IoCFunctionData *selfData = DATA(self);
159 IoTag *t = selfData->typeTag;
160 //IoObject_waitOnFutureIfNeeded(target); future forward will already deal with this?
161 IoObject *result;
163 if (t && t != IoObject_tag(target)) // eliminate t check by matching Object tag?
165 char *a = (char *)IoTag_name(t);
166 char *b = (char *)IoTag_name(IoObject_tag(target));
167 IoState_error_(IOSTATE, m, "CFunction defined for type %s but called on type %s", a, b);
170 //IoState_pushRetainPool(state);
171 result = (*(IoUserFunction *)(selfData->func))(target, locals, m);
172 //IoState_popRetainPoolExceptFor_(state, result);
173 return result;
176 IoObject *IoCFunction_performOn(IoCFunction *self, IoObject *locals, IoMessage *m)
178 /*doc CFunction performOn(target, blockLocals, optionalMessage, optionalContext)
179 Activates the CFunctions with the supplied settings.
182 IoObject *bTarget = IoMessage_locals_valueArgAt_(m, locals, 0);
183 IoObject *bLocals = locals;
184 IoObject *bMessage = m;
185 IoObject *bContext = bTarget;
186 int argCount = IoMessage_argCount(m);
188 if (argCount > 1)
190 bLocals = IoMessage_locals_valueArgAt_(m, locals, 1);
193 if (argCount > 2)
195 bMessage = IoMessage_locals_valueArgAt_(m, locals, 2);
198 if (argCount > 3)
200 bContext = IoMessage_locals_valueArgAt_(m, locals, 3);
203 return IoCFunction_activate(self, bTarget, bLocals, bMessage, bContext);