Beispiel #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;
}
Beispiel #2
0
IoCFFIArray *IoCFFIArray_with(IoCFFIArray *self, IoObject *locals, IoMessage *m)
{
	IoCFFIDataType *type;
	int size, i;
	ffi_type *item_type;
	IoCFFIArray *o = IOCLONE(self);

	IoState_on_doCString_withLabel_(IoObject_state(o), o, "init", "IoCFFIArray_with");

	type = IOCLONE(IoMessage_locals_valueArgAt_(m, locals, 0));
	IoObject_setSlot_to_(o, IOSYMBOL("arrayType"), type);

	size = IoMessage_locals_intArgAt_(m, locals, 1);
	DATA(o)->arraySize = size;

	item_type = IoCFFIDataType_ffiType(type);
	DATA(o)->itemSize = item_type->size;

	// Fake libffi to think we are a Struct
	DATA(o)->ffiType.size = 0;
	DATA(o)->ffiType.alignment = 0;
	DATA(o)->ffiType.type = FFI_TYPE_STRUCT;
	DATA(o)->ffiType.elements = io_calloc(size + 1, sizeof(ffi_type *));
	DATA(o)->needToFreeFFIType = 1;
	for ( i = 0 ; i < size ; i++ ) {
		DATA(o)->ffiType.elements[i] = item_type;
	}
	DATA(o)->ffiType.elements[size] = NULL;

	ffi_cif cif;
	ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &(DATA(o)->ffiType), NULL);

	return o;
}
Beispiel #3
0
IoObject *IoCFFIPointer_atPut(IoCFFIPointer *self, IoObject *locals, IoMessage *m)
{
	int pos;
	IoObject *value, *pointedToType, *d;
	char *ptr;

	//TODO comprobar overrun y coincidencia de tipos
	pos = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0));
	value = IoMessage_locals_valueArgAt_(m, locals, 1);

	pointedToType = IoObject_getSlot_(self, IOSYMBOL("pointedToType"));
	ptr = ((char *)*(DATA(self)->valuePointer)) + (IoCFFIDataType_ffiType(pointedToType)->size * pos);

	d = IOCLONE(pointedToType);
	IoCFFIDataType_rawSetValue(d, value);
	memcpy(ptr, (void *)IoCFFIDataType_ValuePointerFromObject_(NULL, d), IoCFFIDataType_ffiType(pointedToType)->size);

	return self;
}
Beispiel #4
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);
}