diff --git a/platforms/Cross/plugins/SqueakFFIPrims/sqFFIPlugin.c b/platforms/Cross/plugins/SqueakFFIPrims/sqFFIPlugin.c new file mode 100644 index 0000000000..547672a3a4 --- /dev/null +++ b/platforms/Cross/plugins/SqueakFFIPrims/sqFFIPlugin.c @@ -0,0 +1,72 @@ +/**************************************************************************** +* PROJECT: Squeak threaded foreign function interface +* FILE: sqFFIPlugin.c +* CONTENT: C support code for the threaded FFIPlugin +* +* AUTHOR: Eliot Miranda +* +*****************************************************************************/ + +#include +#include /* proto for alloca in MINGW */ +#if !_WIN32 && !__FreeBSD__ && !__OpenBSD__ +# include +#endif +#include + +#ifdef _MSC_VER +# include +# define alloca _alloca +#endif + +/* this is a stub through which floating-point register arguments can be loaded + * prior to an FFI call proper. e.g. on the PowerPC this would be declared as + * extern void loadFloatRegs(double, double, double, double, + * double, double, double, double); + * and called with the appropriate values necessary to load the floating-point + * argument registers. Immediately after the actual call is made, using the + * undisturbed register contents created by the call of loadFloatRegs. + */ +void +loadFloatRegs(void) { return; } + +static FILE *ffiLogFile = NULL; + +int +ffiLogFileNameOfLength(void *nameIndex, int nameLength) +{ + if (nameIndex && nameLength) { + char *fileName; + FILE *fp; + + if (!(fileName = alloca(nameLength+1))) + return 0; + strncpy(fileName, nameIndex, nameLength); + fileName[nameLength] = 0; + /* attempt to open the file and if we can't, fail */ + if (!(fp = fopen(fileName, "at"))) + return 0; + /* close the old log file if needed and use the new one */ + if (ffiLogFile) + fclose(ffiLogFile); + ffiLogFile = fp; + fprintf(ffiLogFile, "------- Log started -------\n"); + fflush(fp); + } + else { + if (ffiLogFile) + fclose(ffiLogFile); + ffiLogFile = NULL; + } + return 1; +} + +int +ffiLogCallOfLength(void *nameIndex, int nameLength) +{ + if (!ffiLogFile) + return 0; + fprintf(ffiLogFile, "%.*s\n", nameLength, (char *)nameIndex); + fflush(ffiLogFile); + return 1; +} diff --git a/platforms/win32/plugins/SqueakFFIPrims/Makefile b/platforms/win32/plugins/SqueakFFIPrims/Makefile index 425e0c044e..fd974d0afb 100644 --- a/platforms/win32/plugins/SqueakFFIPrims/Makefile +++ b/platforms/win32/plugins/SqueakFFIPrims/Makefile @@ -7,7 +7,7 @@ WIN32DIR:= $(PLATDIR)/win32/plugins/$(LIBNAME) %: $(MAKE) -f ../../Makefile.plugin VPATH="$(CROSSDIR) $(MAKERDIR) $(WIN32DIR) $(OBJDIR)" \ - CROSSSRC="sqFFITestFuncs.c sqManualSurface.c" \ + CROSSSRC="sqFFIPlugin.c sqFFITestFuncs.c sqManualSurface.c" \ MAKERSRC="SqueakFFIPrims.c" \ WIN32SRC="" \ $@ diff --git a/platforms/win32/plugins/SqueakFFIPrims/Makefile.msvc b/platforms/win32/plugins/SqueakFFIPrims/Makefile.msvc index 8c1fcc6158..ca2949ba5d 100644 --- a/platforms/win32/plugins/SqueakFFIPrims/Makefile.msvc +++ b/platforms/win32/plugins/SqueakFFIPrims/Makefile.msvc @@ -3,7 +3,7 @@ # Copyright (c) 2020 3D Immersive Collaboration Consulting, LLC ############################################################################# -LIBSRC:=SqueakFFIPrims.c sqFFITestFuncs.c sqManualSurface.c +LIBSRC:=SqueakFFIPrims.c sqFFIPlugin.c sqFFITestFuncs.c sqManualSurface.c include ../common/Makefile.msvc.plugin diff --git a/platforms/win32/plugins/SqueakFFIPrims/Makefile.plugin b/platforms/win32/plugins/SqueakFFIPrims/Makefile.plugin index 1025b6eb00..1484113087 100644 --- a/platforms/win32/plugins/SqueakFFIPrims/Makefile.plugin +++ b/platforms/win32/plugins/SqueakFFIPrims/Makefile.plugin @@ -7,7 +7,7 @@ WIN32DIR:= $(PLATDIR)/win32/plugins/$(LIBNAME) %: $(MAKE) -f ../common/Makefile.plugin VPATH="$(CROSSDIR) $(MAKERDIR) $(WIN32DIR) $(OBJDIR)" \ - CROSSSRC="sqFFITestFuncs.c sqManualSurface.c" \ + CROSSSRC="sqFFIPlugin.c sqFFITestFuncs.c sqManualSurface.c" \ MAKERSRC="SqueakFFIPrims.c" \ WIN32SRC="" \ $@ diff --git a/platforms/win32/plugins/SqueakFFIPrims/sqWin32FFI.c b/platforms/win32/plugins/SqueakFFIPrims/sqWin32FFI.c deleted file mode 100644 index 75c3292b97..0000000000 --- a/platforms/win32/plugins/SqueakFFIPrims/sqWin32FFI.c +++ /dev/null @@ -1,394 +0,0 @@ -/**************************************************************************** -* PROJECT: Squeak foreign function interface -* FILE: sqWin32FFI.c -* CONTENT: Win32 support for the foreign function interface -* -* AUTHOR: Andreas Raab (ar) -* ADDRESS: Walt Disney Imagineering, Glendale, CA -* EMAIL: andreasr@wdi.disney.com -* -*****************************************************************************/ -#include -#include "sq.h" -#include "sqFFI.h" - -extern struct VirtualMachine *interpreterProxy; -#define primitiveFail() interpreterProxy->primitiveFail(); - -#ifdef _MSC_VER -#define LONGLONG __int64 -#endif -#ifdef __GNUC__ -#define LONGLONG long long int -#endif - -#if 0 - -/* Max stack size */ -#define FFI_MAX_ARGS 128 -/* The stack used to assemble the arguments for a call */ -static int ffiArgs[FFI_MAX_ARGS]; -/* The stack pointer while filling the stack */ -static int ffiArgIndex = 0; -/* The area for temporarily allocated strings */ -static char *ffiTempStrings[FFI_MAX_ARGS]; -/* The number of temporarily allocated strings */ -static int ffiTempStringCount = 0; - -/* The return values for calls */ -volatile static int intReturnValue; -volatile static int intReturnValue2; -volatile static double floatReturnValue; -static void* structReturnValue; - -#define ARG_CHECK() if(ffiArgIndex >= FFI_MAX_ARGS) return primitiveFail(); -#define ARG_PUSH(value) { ARG_CHECK(); ffiArgs[ffiArgIndex++] = value; } - - -/*****************************************************************************/ -/*****************************************************************************/ - -/* ffiInitialize: - Announce that the VM is about to do an external function call. */ -int ffiInitialize(void) -{ - ffiArgIndex = 0; - ffiTempStringCount = 0; - return 1; -} - -/* ffiSupportsCallingConvention: - Return true if the support code supports the given calling convention. */ -int ffiSupportsCallingConvention(int callType) -{ - if(callType == FFICallTypeCDecl) return 1; - if(callType == FFICallTypeApi) return 1; - return 0; -} - -int ffiAlloc(int byteSize) -{ - return (int) malloc(byteSize); -} - -int ffiFree(sqIntptr_t ptr) -{ - if(ptr) free((void*)ptr); - return 1; -} - -/*****************************************************************************/ -/*****************************************************************************/ - -int ffiPushSignedChar(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushUnsignedChar(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushSignedByte(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushUnsignedByte(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushSignedShort(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushUnsignedShort(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushSignedInt(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushUnsignedInt(int value) -{ - ARG_PUSH(value); - return 1; -} - -int ffiPushSignedLongLong(int lowWord, int highWord) -{ - ARG_PUSH(lowWord); - ARG_PUSH(highWord); - return 1; -} - -int ffiPushUnsignedLongLong(int lowWord, int highWord) -{ - ARG_PUSH(lowWord); - ARG_PUSH(highWord); - return 1; -} - -int ffiPushSingleFloat(double value) -{ - float floatValue; - floatValue = (float) value; - ARG_PUSH(*(int*)(&floatValue)); - return 1; -} - -int ffiPushDoubleFloat(double value) -{ - ARG_PUSH(((int*)(&value))[0]); - ARG_PUSH(((int*)(&value))[1]); - return 1; -} - -int ffiPushStructureOfLength(int pointer, int* structSpec, int structSize) -{ - int nItems, i; - nItems = ((*structSpec & FFIStructSizeMask) + 3) / 4; - if(pointer == 0) - return primitiveFail(); - for(i=0; i < nItems;i++) - ARG_PUSH(((int*)pointer)[i]); - return 1; -} - -int ffiPushPointer(int pointer) -{ - ARG_PUSH(pointer); - return 1; -} - -int ffiPushStringOfLength(int srcIndex, int length) -{ - char *ptr; - ARG_CHECK(); /* fail before allocating */ - ptr = (char*) malloc(length+1); - if(!ptr) return primitiveFail(); - memcpy(ptr, (void*)srcIndex, length); - ptr[length] = 0; - ffiTempStrings[ffiTempStringCount++] = ptr; - ARG_PUSH((int)ptr); - return 1; -} - -/*****************************************************************************/ -/*****************************************************************************/ - -/* ffiCanReturn: - Return true if the support code can return the given type. */ -int ffiCanReturn(int *structSpec, int specSize) -{ - int header = *structSpec; - if(header & FFIFlagPointer) return 1; - if(header & FFIFlagStructure) { - int structSize = header & FFIStructSizeMask; - if(structSize > 8) { - structReturnValue = malloc(structSize); - if(!structReturnValue) return 0; - ARG_PUSH((int)structReturnValue); - } - } - return 1; -} - -/* ffiReturnFloatValue: - Return the value from a previous ffi call with float return type. */ -double ffiReturnFloatValue(void) -{ - return floatReturnValue; -} - -/* ffiLongLongResultLow: - Return the low 32bit from the 64bit result of a call to an external function */ -int ffiLongLongResultLow(void) -{ - return intReturnValue; -} - -/* ffiLongLongResultHigh: - Return the high 32bit from the 64bit result of a call to an external function */ -int ffiLongLongResultHigh(void) -{ - return intReturnValue2; -} - -/* ffiStoreStructure: - Store the structure result of a previous ffi call into the given address. - Note: Since the ST allocator always allocates multiples of 32bit we can - use the atomic types for storing <= 64bit result structures. */ -int ffiStoreStructure(int address, int structSize) -{ - if(structSize <= 4) { - *(int*)address = intReturnValue; - return 1; - } - if(structSize <= 8) { - *(int*)address = intReturnValue; - *(int*)(address+4) = intReturnValue2; - return 1; - } - /* assume pointer to hidden structure */ - memcpy((void*)address, (void*) structReturnValue, structSize); - return 1; -} - -/* ffiCleanup: - Cleanup after a foreign function call has completed. */ -int ffiCleanup(void) -{ - int i; - for(i=0; i