Example #1
0
IoObject *IoCFFIFunction_call(IoCFFIFunction *self, IoObject *locals, IoMessage *m)
{
	IoCFFILibrary *library;
	const char *funName;
	void *funPointer, **funArgVals, *funRetVal;
	ffi_type **funArgTypes, *funRetType;
	ffi_cif *funInterface;
	int funArgCount, i;
	ffi_status status;
	IoObject *returnValAsObj, *funRetTypeObject, *o;
	List *funArgTypeObjects;

	library = IoObject_getSlot_(self, IOSYMBOL("library"));
	funInterface = &(DATA(self)->interface);
	funName = CSTRING(IoObject_getSlot_(self, IOSYMBOL("name")));
	funPointer = IoCFFILibrary_rawGetFuctionPointer_(library, funName);
	funArgTypeObjects = IoList_rawList(IoObject_getSlot_(self, IOSYMBOL("argumentTypes")));
	funRetTypeObject = IoObject_getSlot_(self, IOSYMBOL("returnType"));

	funArgCount = (int)List_size(funArgTypeObjects);
	funArgTypes = calloc(funArgCount, sizeof(ffi_type *));
	for (i = 0; i < funArgCount; i++)
	{
		o = List_at_(funArgTypeObjects, i);
		funArgTypes[i] = IoCFFIDataType_ffiType(o);
	}
	funRetType = IoCFFIDataType_ffiType(funRetTypeObject);

	status = ffi_prep_cif(funInterface, FFI_DEFAULT_ABI, funArgCount, funRetType, funArgTypes);
	if (status != FFI_OK)
	{
		printf("\n\nUh oh.  Something went wrong in IoCFFIFunction_call.\n\n");
		free(funArgTypes);
		return IONIL(self);
	}

	funArgVals = calloc(funArgCount, sizeof(void *));
	funRetVal = calloc(1, funRetType->size);
	IoState_pushCollectorPause(IOSTATE);
	{
		for (i = 0; i < funArgCount; i++)
		{
			o = IoMessage_locals_valueArgAt_(m, locals, i);
			funArgVals[i] = IoCFFIDataType_ValuePointerFromObject_(o);
		}

		ffi_call(funInterface, funPointer, funRetVal, funArgVals);
		returnValAsObj = IoCFFIDataType_objectFromData_(funRetTypeObject, funRetVal);
	}
	IoState_popCollectorPause(IOSTATE);

	free(funArgTypes);
	free(funArgVals);
	free(funRetVal);

	return returnValAsObj;
}
Example #2
0
IoCFFIArray *IoCFFIArray_at(IoCFFIArray *self, IoObject *locals, IoMessage *m)
{
	int pos;
	char *ptr;

	//TODO check limits
	pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0));
	ptr = ((char *)DATA(self)->buffer) + (DATA(self)->itemSize * pos);
	return IoCFFIDataType_objectFromData_(IoObject_getSlot_(self, IOSYMBOL("arrayType")), (void *)ptr);
}
Example #3
0
IoObject *IoCFFIPointer_at(IoCFFIPointer *self, IoObject *locals, IoMessage *m)
{
	int pos;
	IoObject *pointedToType;
	char *ptr;

	pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0));
	pointedToType = IoObject_getSlot_(self, IOSYMBOL("pointedToType"));
	ptr = ((char *)*(DATA(self)->valuePointer)) + (IoCFFIDataType_ffiType(pointedToType)->size * pos);
	
	return IoCFFIDataType_objectFromData_(pointedToType, (void *)ptr);
}
Example #4
0
IoCFFIArray *IoCFFIArray_at(IoCFFIArray *self, IoObject *locals, IoMessage *m)
{
	int pos;
	char *ptr;

	pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0));

	if ( pos >= DATA(self)->arraySize ) {
		IoState_error_(IOSTATE, m, "index out of bounds");
		return IONIL(self);
	}

	ptr = ((char *)DATA(self)->buffer) + (DATA(self)->itemSize * pos);
	return IoCFFIDataType_objectFromData_(IoObject_getSlot_(self, IOSYMBOL("arrayType")), (void *)ptr);
}
Example #5
0
IoObject *IoCFFIPointer_value(IoCFFIPointer *self, IoObject *locals, IoMessage *m)
{
	IoObject *pointedToType;
	IoCFFIPointer *pointer;
	char *typeString, *cp, c;

	if (*(DATA(self)->valuePointer) == NULL)
	{
		//IoState_error_(IOSTATE, m, "attempt to dereference NULL pointer");
		return IONIL(self);
	}

    typeString = CSTRING(IoState_on_doCString_withLabel_(IOSTATE, self, "typeString", "IoCFFIPointer_value"));

    pointedToType = IoObject_getSlot_(self, IOSYMBOL("pointedToType"));

	if (ISCFFIPointer(pointedToType))
	{
		// we are a pointer to a pointer, so return a new Pointer
		// that points to the address of our ptr dereferenced

		cp = strrchr(typeString, '^');
		switch (c = *(++cp))
		{

#define IoCFFIPointer_value_SET_DATA_PTR(cType) \
	pointer = IOCLONE(IoCFFIPointer_ToType_(IoObject_getSlot_(pointedToType, IOSYMBOL("pointedToType")))); \
	*(DATA(pointer)->valuePointer) = *((cType **)(*(DATA(self)->valuePointer))); break
	//DATA(pointer)->ptr = *((cType **)(DATA(self)->ptr)); break

			case 'c':
			case 'b':
				IoCFFIPointer_value_SET_DATA_PTR(char);
			case 'C':
			case 'B':
				IoCFFIPointer_value_SET_DATA_PTR(unsigned char);
			case 's':
				IoCFFIPointer_value_SET_DATA_PTR(short);
			case 'S':
				IoCFFIPointer_value_SET_DATA_PTR(unsigned short);
			case 'i':
				IoCFFIPointer_value_SET_DATA_PTR(int);
			case 'I':
				IoCFFIPointer_value_SET_DATA_PTR(unsigned int);
			case 'l':
				IoCFFIPointer_value_SET_DATA_PTR(long);
			case 'L':
				IoCFFIPointer_value_SET_DATA_PTR(unsigned long);
			case 'f':
				IoCFFIPointer_value_SET_DATA_PTR(float);
			case 'd':
				IoCFFIPointer_value_SET_DATA_PTR(double);
			case '*':
				IoCFFIPointer_value_SET_DATA_PTR(char *);
			case '{':
			case '(':
			case '&':
			case '[':
			case 'v':
				IoCFFIPointer_value_SET_DATA_PTR(void);

#undef IoCFFIPointer_value_SET_DATA_PTR

			//case 'v':
			//	IoState_error_(IOSTATE, m, "attempt to dereference a void pointer");
			//	return IONIL(self);

			default:
				IoState_error_(IOSTATE, m, "unknown character '%c' in Pointer typeString", c);
				return IONIL(self);
			}
			return pointer;
	}
	else if(ISCFFIDataType(pointedToType) || ISCFFIStructure(pointedToType) || ISCFFIFunction(pointedToType) || ISCFFIArray(pointedToType))
	{
		return IoCFFIDataType_objectFromData_(pointedToType, *(DATA(self)->valuePointer));
	}
    else
	{
		IoState_error_(IOSTATE, m, "attempt to dereference Pointer object whose pointedToType is unknown.");
		return IONIL(self);
	}
}