ExternalFunctionCallback.st
changeset 22545 d5b6e2585870
parent 21623 0fd2de531f9a
child 22546 4f467704d94e
--- a/ExternalFunctionCallback.st	Mon Feb 19 14:44:46 2018 +0100
+++ b/ExternalFunctionCallback.st	Mon Feb 19 14:48:01 2018 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 2007 by eXept Software AG
 	      All Rights Reserved
@@ -380,6 +382,10 @@
 
 callTypeOLE
     ^ ExternalLibraryFunction callTypeOLE
+!
+
+callTypeUNIX64
+    ^ ExternalLibraryFunction callTypeUNIX64
 ! !
 
 !ExternalFunctionCallback class methodsFor:'helpers'!
@@ -467,6 +473,10 @@
     "Created: / 01-08-2006 / 15:12:40 / cg"
 !
 
+beCallTypeUNIX64
+    flags := (flags ? 0) bitOr: (self class callTypeUNIX64).
+!
+
 beCallTypeWINAPI
     self beCallTypeAPI
 
@@ -509,12 +519,6 @@
 
 !ExternalFunctionCallback methodsFor:'generation'!
 
-getCode
-    ^ super code
-
-    "Created: / 03-03-2017 / 13:55:00 / cg"
-!
-
 code
     self hasCode ifFalse:[
 	self generateClosure
@@ -522,6 +526,12 @@
     ^ super code
 
     "Created: / 11-06-2007 / 15:53:00 / cg"
+!
+
+getCode
+    ^ super code
+
+    "Created: / 03-03-2017 / 13:55:00 / cg"
 ! !
 
 !ExternalFunctionCallback methodsFor:'private-accessing'!
@@ -555,9 +565,9 @@
     ffi_abi __callType = FFI_DEFAULT_ABI;
     int __numArgsWanted;
     struct closurePlusCIF {
-	ffi_closure closure;
-	ffi_cif cif;
-	ffi_type *argTypes[MAX_ARGS];
+        ffi_closure closure;
+        ffi_cif cif;
+        ffi_type *argTypes[MAX_ARGS];
     } *closurePlusCIFp;
     ffi_closure *pcl;
     ffi_cif *cif;
@@ -569,248 +579,250 @@
     pcl = &(closurePlusCIFp->closure);
 
 #   define __FAIL__(fcode) \
-	{ \
-	    failureCode = fcode; free(closurePlusCIFp); goto getOutOfHere; \
-	}
+        { \
+            failureCode = fcode; free(closurePlusCIFp); goto getOutOfHere; \
+        }
 
     if (argTypeSymbols == nil) {
-	__numArgsWanted = 0;
+        __numArgsWanted = 0;
     } else if (__isArrayLike(argTypeSymbols)) {
-	__numArgsWanted = __arraySize(argTypeSymbols);
+        __numArgsWanted = __arraySize(argTypeSymbols);
     } else {
-	__FAIL__(@symbol(BadArgumentTypeVector))
+        __FAIL__(@symbol(BadArgumentTypeVector))
     }
 
     if (__numArgsWanted > MAX_ARGS) {
-	__FAIL__(@symbol(TooManyArguments))
+        __FAIL__(@symbol(TooManyArguments))
     }
 
     /*
      * validate the return type
      */
     if (returnTypeSymbol == @symbol(voidPointer)) {
-	returnTypeSymbol = @symbol(handle);
+        returnTypeSymbol = @symbol(handle);
     }
 
     if (returnTypeSymbol == @symbol(int)) {
-	__returnType = __get_ffi_type_sint();
+        __returnType = __get_ffi_type_sint();
     } else if (returnTypeSymbol == @symbol(uint)) {
-	__returnType = __get_ffi_type_uint();
+        __returnType = __get_ffi_type_uint();
     } else if (returnTypeSymbol == @symbol(uint8)) {
-	__returnType = __get_ffi_type_uint8();
+        __returnType = __get_ffi_type_uint8();
     } else if (returnTypeSymbol == @symbol(uint16)) {
-	__returnType = __get_ffi_type_uint16();
+        __returnType = __get_ffi_type_uint16();
     } else if (returnTypeSymbol == @symbol(uint32)) {
-	__returnType = __get_ffi_type_uint32();
+        __returnType = __get_ffi_type_uint32();
     } else if (returnTypeSymbol == @symbol(uint64)) {
-	__returnType = __get_ffi_type_uint64();
+        __returnType = __get_ffi_type_uint64();
 
     } else if (returnTypeSymbol == @symbol(sint)) {
-	__returnType = __get_ffi_type_sint();
+        __returnType = __get_ffi_type_sint();
     } else if (returnTypeSymbol == @symbol(sint8)) {
-	__returnType = __get_ffi_type_sint8();
+        __returnType = __get_ffi_type_sint8();
     } else if (returnTypeSymbol == @symbol(sint16)) {
-	__returnType = __get_ffi_type_sint16();
+        __returnType = __get_ffi_type_sint16();
     } else if (returnTypeSymbol == @symbol(sint32)) {
-	__returnType = __get_ffi_type_sint32();
+        __returnType = __get_ffi_type_sint32();
     } else if (returnTypeSymbol == @symbol(sint64)) {
-	__returnType = __get_ffi_type_sint64();
+        __returnType = __get_ffi_type_sint64();
 
     } else if (returnTypeSymbol == @symbol(long)) {
-	if (sizeof(long) == 4) {
-	   returnTypeSymbol = @symbol(sint32);
-	   __returnType = __get_ffi_type_sint32();
-	} else if (sizeof(long) == 8) {
-	   returnTypeSymbol = @symbol(sint64);
-	   __returnType = __get_ffi_type_sint64();
-	} else {
-	    __FAIL__(@symbol(UnknownReturnType))
-	}
+        if (sizeof(long) == 4) {
+           returnTypeSymbol = @symbol(sint32);
+           __returnType = __get_ffi_type_sint32();
+        } else if (sizeof(long) == 8) {
+           returnTypeSymbol = @symbol(sint64);
+           __returnType = __get_ffi_type_sint64();
+        } else {
+            __FAIL__(@symbol(UnknownReturnType))
+        }
 
     } else if (returnTypeSymbol == @symbol(ulong)) {
-	if (sizeof(long) == 4) {
-	   returnTypeSymbol = @symbol(uint32);
-	   __returnType = __get_ffi_type_uint32();
-	}else if (sizeof(long) == 8) {
-	   returnTypeSymbol = @symbol(uint64);
-	   __returnType = __get_ffi_type_uint64();
-	} else {
-	    __FAIL__(@symbol(UnknownReturnType))
-	}
+        if (sizeof(long) == 4) {
+           returnTypeSymbol = @symbol(uint32);
+           __returnType = __get_ffi_type_uint32();
+        }else if (sizeof(long) == 8) {
+           returnTypeSymbol = @symbol(uint64);
+           __returnType = __get_ffi_type_uint64();
+        } else {
+            __FAIL__(@symbol(UnknownReturnType))
+        }
 
     } else if (returnTypeSymbol == @symbol(bool)) {
-	__returnType = __get_ffi_type_uint();
+        __returnType = __get_ffi_type_uint();
 
     } else if (returnTypeSymbol == @symbol(float)) {
-	__returnType = __get_ffi_type_float();
+        __returnType = __get_ffi_type_float();
     } else if (returnTypeSymbol == @symbol(double)) {
-	__returnType = __get_ffi_type_double();
+        __returnType = __get_ffi_type_double();
 
     } else if (returnTypeSymbol == @symbol(void)) {
-	__returnType = __get_ffi_type_void();
+        __returnType = __get_ffi_type_void();
     } else if ((returnTypeSymbol == @symbol(pointer))
-	       || (returnTypeSymbol == @symbol(handle))
-	       || (returnTypeSymbol == @symbol(charPointer))
-	       || (returnTypeSymbol == @symbol(bytePointer))
-	       || (returnTypeSymbol == @symbol(floatPointer))
-	       || (returnTypeSymbol == @symbol(doublePointer))
-	       || (returnTypeSymbol == @symbol(intPointer))
-	       || (returnTypeSymbol == @symbol(shortPointer))
-	       || (returnTypeSymbol == @symbol(wcharPointer))) {
-	__returnType = __get_ffi_type_pointer();
+               || (returnTypeSymbol == @symbol(handle))
+               || (returnTypeSymbol == @symbol(charPointer))
+               || (returnTypeSymbol == @symbol(bytePointer))
+               || (returnTypeSymbol == @symbol(floatPointer))
+               || (returnTypeSymbol == @symbol(doublePointer))
+               || (returnTypeSymbol == @symbol(intPointer))
+               || (returnTypeSymbol == @symbol(shortPointer))
+               || (returnTypeSymbol == @symbol(wcharPointer))) {
+        __returnType = __get_ffi_type_pointer();
     } else {
-	if (__isSymbol(returnTypeSymbol)
-	 && ((returnValueClass = __GLOBAL_GET(returnTypeSymbol)) != nil)) {
-	    if (! __isBehaviorLike(returnValueClass)) {
-		__FAIL__(@symbol(NonBehaviorReturnType))
-	    }
-	    if (! __qIsSubclassOfExternalAddress(returnValueClass)) {
-		__FAIL__(@symbol(NonExternalAddressReturnType))
-	    }
-	    __returnType = __get_ffi_type_pointer();
-	    returnTypeSymbol = @symbol(pointer);
-	} else {
-	    __FAIL__(@symbol(UnknownReturnType))
-	}
+        if (__isSymbol(returnTypeSymbol)
+         && ((returnValueClass = __GLOBAL_GET(returnTypeSymbol)) != nil)) {
+            if (! __isBehaviorLike(returnValueClass)) {
+                __FAIL__(@symbol(NonBehaviorReturnType))
+            }
+            if (! __qIsSubclassOfExternalAddress(returnValueClass)) {
+                __FAIL__(@symbol(NonExternalAddressReturnType))
+            }
+            __returnType = __get_ffi_type_pointer();
+            returnTypeSymbol = @symbol(pointer);
+        } else {
+            __FAIL__(@symbol(UnknownReturnType))
+        }
     }
 
     /*
      * setup arg-buffers
      */
     for (i=0; i<__numArgsWanted; i++) {
-	ffi_type *thisType;
-	void *argValuePtr;
-	OBJ typeSymbol;
+        ffi_type *thisType;
+        void *argValuePtr;
+        OBJ typeSymbol;
 
-	failureInfo = __mkSmallInteger(i+1);   /* in case there is one */
+        failureInfo = __mkSmallInteger(i+1);   /* in case there is one */
 
-	typeSymbol = __ArrayInstPtr(argTypeSymbols)->a_element[i];
+        typeSymbol = __ArrayInstPtr(argTypeSymbols)->a_element[i];
 
-	if (typeSymbol == @symbol(handle)) {
-	    typeSymbol = @symbol(pointer);
-	} else if (typeSymbol == @symbol(voidPointer)) {
-	    typeSymbol = @symbol(pointer);
-	}
+        if (typeSymbol == @symbol(handle)) {
+            typeSymbol = @symbol(pointer);
+        } else if (typeSymbol == @symbol(voidPointer)) {
+            typeSymbol = @symbol(pointer);
+        }
 
-	if (typeSymbol == @symbol(long)) {
-	    if (sizeof(long) == sizeof(int)) {
-		typeSymbol = @symbol(sint);
-	    } else {
-		if (sizeof(long) == 4) {
-		    typeSymbol = @symbol(sint32);
-		} else if (sizeof(long) == 8) {
-		    typeSymbol = @symbol(sint64);
-		}
-	    }
-	}
-	if (typeSymbol == @symbol(ulong)) {
-	    if (sizeof(unsigned long) == sizeof(unsigned int)) {
-		typeSymbol = @symbol(uint);
-	    } else {
-		if (sizeof(long) == 4) {
-		    typeSymbol = @symbol(uint32);
-		} else if (sizeof(long) == 8) {
-		    typeSymbol = @symbol(uint64);
-		}
-	    }
-	}
+        if (typeSymbol == @symbol(long)) {
+            if (sizeof(long) == sizeof(int)) {
+                typeSymbol = @symbol(sint);
+            } else {
+                if (sizeof(long) == 4) {
+                    typeSymbol = @symbol(sint32);
+                } else if (sizeof(long) == 8) {
+                    typeSymbol = @symbol(sint64);
+                }
+            }
+        }
+        if (typeSymbol == @symbol(ulong)) {
+            if (sizeof(unsigned long) == sizeof(unsigned int)) {
+                typeSymbol = @symbol(uint);
+            } else {
+                if (sizeof(long) == 4) {
+                    typeSymbol = @symbol(uint32);
+                } else if (sizeof(long) == 8) {
+                    typeSymbol = @symbol(uint64);
+                }
+            }
+        }
 
-	if (typeSymbol == @symbol(int)) {
-	    thisType = __get_ffi_type_sint();
-	} else if (typeSymbol == @symbol(uint)) {
-	    thisType = __get_ffi_type_uint();
-	} else if (typeSymbol == @symbol(uint8)) {
-	    thisType = __get_ffi_type_uint8();
-	} else if (typeSymbol == @symbol(sint8)) {
-	    thisType = __get_ffi_type_sint8();
-	} else if (typeSymbol == @symbol(uint16)) {
-	    thisType = __get_ffi_type_uint16();
-	} else if (typeSymbol == @symbol(sint16)) {
-	    thisType = __get_ffi_type_sint16();
-	} else if ((typeSymbol == @symbol(uint32)) || (typeSymbol == @symbol(sint32))) {
-	    thisType = __get_ffi_type_uint32();
-	} else if (typeSymbol == @symbol(float)) {
-	    thisType = __get_ffi_type_float();
-	} else if (typeSymbol == @symbol(double)) {
-	    thisType = __get_ffi_type_double();
-	} else if (typeSymbol == @symbol(void)) {
-	    thisType = __get_ffi_type_void();
-	} else if (typeSymbol == @symbol(charPointer)) {
-	    thisType = __get_ffi_type_pointer();
-	} else if (typeSymbol == @symbol(floatPointer)) {
-	    thisType = __get_ffi_type_pointer();
-	} else if (typeSymbol == @symbol(doublePointer)) {
-	    thisType = __get_ffi_type_pointer();
-	} else if (typeSymbol == @symbol(pointer)) {
+        if (typeSymbol == @symbol(int)) {
+            thisType = __get_ffi_type_sint();
+        } else if (typeSymbol == @symbol(uint)) {
+            thisType = __get_ffi_type_uint();
+        } else if (typeSymbol == @symbol(uint8)) {
+            thisType = __get_ffi_type_uint8();
+        } else if (typeSymbol == @symbol(sint8)) {
+            thisType = __get_ffi_type_sint8();
+        } else if (typeSymbol == @symbol(uint16)) {
+            thisType = __get_ffi_type_uint16();
+        } else if (typeSymbol == @symbol(sint16)) {
+            thisType = __get_ffi_type_sint16();
+        } else if ((typeSymbol == @symbol(uint32)) || (typeSymbol == @symbol(sint32))) {
+            thisType = __get_ffi_type_uint32();
+        } else if (typeSymbol == @symbol(float)) {
+            thisType = __get_ffi_type_float();
+        } else if (typeSymbol == @symbol(double)) {
+            thisType = __get_ffi_type_double();
+        } else if (typeSymbol == @symbol(void)) {
+            thisType = __get_ffi_type_void();
+        } else if (typeSymbol == @symbol(charPointer)) {
+            thisType = __get_ffi_type_pointer();
+        } else if (typeSymbol == @symbol(floatPointer)) {
+            thisType = __get_ffi_type_pointer();
+        } else if (typeSymbol == @symbol(doublePointer)) {
+            thisType = __get_ffi_type_pointer();
+        } else if (typeSymbol == @symbol(pointer)) {
 commonPointerTypeArg: ;
-	    thisType = __get_ffi_type_pointer();
-	} else if (typeSymbol == @symbol(bool)) {
-	    thisType = __get_ffi_type_uint();
-	} else if (__isSymbol(typeSymbol)
-	     && ((argValueClass = __GLOBAL_GET(typeSymbol)) != nil)) {
-	    if (! __isBehaviorLike(argValueClass)) {
-		__FAIL__(@symbol(NonBehaviorArgumentType))
-	    }
-	    if (! __qIsSubclassOfExternalAddress(argValueClass)) {
-		__FAIL__(@symbol(NonExternalAddressArgumentType))
-	    }
-	    goto commonPointerTypeArg; /* sorry */
-	} else {
-	    __FAIL__(@symbol(UnknownArgumentType))
-	}
+            thisType = __get_ffi_type_pointer();
+        } else if (typeSymbol == @symbol(bool)) {
+            thisType = __get_ffi_type_uint();
+        } else if (__isSymbol(typeSymbol)
+             && ((argValueClass = __GLOBAL_GET(typeSymbol)) != nil)) {
+            if (! __isBehaviorLike(argValueClass)) {
+                __FAIL__(@symbol(NonBehaviorArgumentType))
+            }
+            if (! __qIsSubclassOfExternalAddress(argValueClass)) {
+                __FAIL__(@symbol(NonExternalAddressArgumentType))
+            }
+            goto commonPointerTypeArg; /* sorry */
+        } else {
+            __FAIL__(@symbol(UnknownArgumentType))
+        }
 
-	closurePlusCIFp->argTypes[i] = thisType;
+        closurePlusCIFp->argTypes[i] = thisType;
     }
     failureInfo = nil;
 
     __callType = FFI_DEFAULT_ABI;
-
+#ifdef __osx__
+    __callType = CALLTYPE_FFI_UNIX64;
+#else
     if (callTypeNumber != nil) {
-#ifdef CALLTYPE_FFI_STDCALL
-	if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_API)) {
-	    __callType = CALLTYPE_FFI_STDCALL;
-	}
+# ifdef CALLTYPE_FFI_STDCALL
+        if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_API)) {
+            __callType = CALLTYPE_FFI_STDCALL;
+        }
+# endif
+# ifdef CALLTYPE_FFI_V8
+        if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_V8)) {
+            __callType = CALLTYPE_FFI_V8;
+        }
+# endif
+# ifdef CALLTYPE_FFI_V9
+        if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_V9)) {
+            __callType = CALLTYPE_FFI_V9;
+        }
+# endif
+# ifdef CALLTYPE_FFI_UNIX64
+        if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_UNIX64)) {
+            __callType = CALLTYPE_FFI_UNIX64;
+        }
+# endif
+    }
 #endif
-#ifdef CALLTYPE_FFI_V8
-	if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_V8)) {
-	    __callType = CALLTYPE_FFI_V8;
-	}
-#endif
-#ifdef CALLTYPE_FFI_V9
-	if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_V9)) {
-	    __callType = CALLTYPE_FFI_V9;
-	}
-#endif
-#ifdef CALLTYPE_FFI_UNIX64
-	if (callTypeNumber == @global(ExternalLibraryFunction:CALLTYPE_UNIX64)) {
-	    __callType = CALLTYPE_FFI_UNIX64;
-	}
-#endif
+    if (@global(ExternalFunctionCallback:Verbose) == true) {
+        printf("prep_cif cif-ptr=%"_lx_"\n", (INT)cif);
+    }
+
+    if (ffi_prep_cif(cif, __callType, __numArgsWanted, __returnType, argTypePtrs) != FFI_OK) {
+        __FAIL__(@symbol(FFIPrepareFailed))
     }
 
     if (@global(ExternalFunctionCallback:Verbose) == true) {
-	printf("prep_cif cif-ptr=%"_lx_"\n", (INT)cif);
-    }
-
-    if (ffi_prep_cif(cif, __callType, __numArgsWanted, __returnType, argTypePtrs) != FFI_OK) {
-	__FAIL__(@symbol(FFIPrepareFailed))
-    }
-
-    if (@global(ExternalFunctionCallback:Verbose) == true) {
-	printf("closure is 0x%"_lx_" (%d bytes)\n", (INT)pcl, (int)sizeof(ffi_closure));
-	printf("index is %"_ld_"\n", __intVal(callBackIndex));
+        printf("closure is 0x%"_lx_" (%d bytes)\n", (INT)pcl, (int)sizeof(ffi_closure));
+        printf("index is %"_ld_"\n", __intVal(callBackIndex));
     }
     if (ffi_prep_closure(pcl, cif, ExternalFunctionCallback__closure_wrapper_fn, (void *)(__intVal(callBackIndex)) /* userdata */) != FFI_OK) {
-	__FAIL__(@symbol(FFIPrepareClosureFailed))
+        __FAIL__(@symbol(FFIPrepareClosureFailed))
     }
     if (@global(ExternalFunctionCallback:Verbose) == true) {
-	printf("pcl->cif is 0x%"_lx_"\n", (INT)(pcl->cif));
-	printf("pcl->fun is 0x%"_lx_"\n", (INT)(pcl->fun));
-	printf("pcl code at %"_lx_" is:\n", (INT)pcl);
-	printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[0],((unsigned char *)pcl)[1],((unsigned char *)pcl)[2],((unsigned char *)pcl)[3]);
-	printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[4],((unsigned char *)pcl)[5],((unsigned char *)pcl)[6],((unsigned char *)pcl)[7]);
-	printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[8],((unsigned char *)pcl)[9],((unsigned char *)pcl)[10],((unsigned char *)pcl)[11]);
-	printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[12],((unsigned char *)pcl)[13],((unsigned char *)pcl)[14],((unsigned char *)pcl)[15]);
+        printf("pcl->cif is 0x%"_lx_"\n", (INT)(pcl->cif));
+        printf("pcl->fun is 0x%"_lx_"\n", (INT)(pcl->fun));
+        printf("pcl code at %"_lx_" is:\n", (INT)pcl);
+        printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[0],((unsigned char *)pcl)[1],((unsigned char *)pcl)[2],((unsigned char *)pcl)[3]);
+        printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[4],((unsigned char *)pcl)[5],((unsigned char *)pcl)[6],((unsigned char *)pcl)[7]);
+        printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[8],((unsigned char *)pcl)[9],((unsigned char *)pcl)[10],((unsigned char *)pcl)[11]);
+        printf("  %02x %02x %02x %02x\n", ((unsigned char *)pcl)[12],((unsigned char *)pcl)[13],((unsigned char *)pcl)[14],((unsigned char *)pcl)[15]);
     }
     __INST(code_) = (OBJ)pcl;
 
@@ -824,8 +836,8 @@
 getOutOfHere: ;
 %}.
     failureCode notNil ifTrue:[
-	self primitiveFailed:(failureCode->failureInfo).   "see failureCode and failureInfo for details"
-	^ nil
+        self primitiveFailed:(failureCode->failureInfo).   "see failureCode and failureInfo for details"
+        ^ nil
     ].
 
     "Created: / 11-06-2007 / 21:53:02 / cg"
@@ -859,3 +871,4 @@
 version_CVS
     ^ '$Header$'
 ! !
+