11 " |
11 " |
12 "{ Package: 'stx:libbasic' }" |
12 "{ Package: 'stx:libbasic' }" |
13 |
13 |
14 ExternalFunction subclass:#ExternalLibraryFunction |
14 ExternalFunction subclass:#ExternalLibraryFunction |
15 instanceVariableNames:'flags moduleName returnType argumentTypes owningClass' |
15 instanceVariableNames:'flags moduleName returnType argumentTypes owningClass' |
16 classVariableNames:'DLLPATH FLAG_VIRTUAL FLAG_NONVIRTUAL FLAG_ASYNC |
16 classVariableNames:'DLLPATH FLAG_VIRTUAL FLAG_NONVIRTUAL FLAG_OBJECTIVEC FLAG_ASYNC |
17 FLAG_UNLIMITEDSTACK FLAG_RETVAL_IS_CONST CALLTYPE_MASK |
17 FLAG_UNLIMITEDSTACK FLAG_RETVAL_IS_CONST CALLTYPE_MASK |
18 CALLTYPE_API CALLTYPE_C CALLTYPE_OLE CALLTYPE_V8 CALLTYPE_V9 |
18 CALLTYPE_API CALLTYPE_C CALLTYPE_OLE CALLTYPE_V8 CALLTYPE_V9 |
19 CALLTYPE_UNIX64 DllMapping' |
19 CALLTYPE_UNIX64 DllMapping' |
20 poolDictionaries:'' |
20 poolDictionaries:'' |
21 category:'System-Support' |
21 category:'System-Support' |
26 |
26 |
27 #ifdef HAVE_FFI |
27 #ifdef HAVE_FFI |
28 # include <ffi.h> |
28 # include <ffi.h> |
29 # define MAX_ARGS 128 |
29 # define MAX_ARGS 128 |
30 |
30 |
|
31 # ifdef USE_STANDARD_FFI |
|
32 # define __get_ffi_type_sint() &ffi_type_sint |
|
33 # define __get_ffi_type_sint8() &ffi_type_sint8 |
|
34 # define __get_ffi_type_sint16() &ffi_type_sint16 |
|
35 # define __get_ffi_type_sint32() &ffi_type_sint32 |
|
36 # define __get_ffi_type_sint64() &ffi_type_sint64 |
|
37 # define __get_ffi_type_uint() &ffi_type_uint |
|
38 # define __get_ffi_type_uint8() &ffi_type_uint8 |
|
39 # define __get_ffi_type_uint16() &ffi_type_uint16 |
|
40 # define __get_ffi_type_uint32() &ffi_type_uint32 |
|
41 # define __get_ffi_type_uint64() &ffi_type_uint64 |
|
42 # define __get_ffi_type_float() &ffi_type_float |
|
43 # define __get_ffi_type_double() &ffi_type_double |
|
44 # define __get_ffi_type_void() &ffi_type_void |
|
45 # define __get_ffi_type_pointer() &ffi_type_pointer |
|
46 # else |
31 extern ffi_type *__get_ffi_type_sint(); |
47 extern ffi_type *__get_ffi_type_sint(); |
32 extern ffi_type *__get_ffi_type_sint8(); |
48 extern ffi_type *__get_ffi_type_sint8(); |
33 extern ffi_type *__get_ffi_type_sint16(); |
49 extern ffi_type *__get_ffi_type_sint16(); |
34 extern ffi_type *__get_ffi_type_sint32(); |
50 extern ffi_type *__get_ffi_type_sint32(); |
35 extern ffi_type *__get_ffi_type_sint64(); |
51 extern ffi_type *__get_ffi_type_sint64(); |
213 |
230 |
214 DLLPATH isNil ifTrue:[ |
231 DLLPATH isNil ifTrue:[ |
215 DLLPATH := #('.'). |
232 DLLPATH := #('.'). |
216 FLAG_VIRTUAL := %{ __MKSMALLINT(__EXTL_FLAG_VIRTUAL) %}. "/ a virtual c++ call |
233 FLAG_VIRTUAL := %{ __MKSMALLINT(__EXTL_FLAG_VIRTUAL) %}. "/ a virtual c++ call |
217 FLAG_NONVIRTUAL := %{ __MKSMALLINT(__EXTL_FLAG_NONVIRTUAL) %}. "/ a non-virtual c++ call |
234 FLAG_NONVIRTUAL := %{ __MKSMALLINT(__EXTL_FLAG_NONVIRTUAL) %}. "/ a non-virtual c++ call |
|
235 FLAG_OBJECTIVEC := %{ __MKSMALLINT(__EXTL_FLAG_OBJECTIVEC) %}. "/ an objectiveC message send |
218 FLAG_UNLIMITEDSTACK := %{ __MKSMALLINT(__EXTL_FLAG_UNLIMITEDSTACK) %}. "/ unlimitedstack under unix |
236 FLAG_UNLIMITEDSTACK := %{ __MKSMALLINT(__EXTL_FLAG_UNLIMITEDSTACK) %}. "/ unlimitedstack under unix |
219 FLAG_ASYNC := %{ __MKSMALLINT(__EXTL_FLAG_ASYNC) %}. "/ async under win32 |
237 FLAG_ASYNC := %{ __MKSMALLINT(__EXTL_FLAG_ASYNC) %}. "/ async under win32 |
220 FLAG_RETVAL_IS_CONST := %{ __MKSMALLINT(__EXTL_FLAG_RETVAL_IS_CONST) %}."/ return value is not to be registered for finalization |
238 FLAG_RETVAL_IS_CONST := %{ __MKSMALLINT(__EXTL_FLAG_RETVAL_IS_CONST) %}."/ return value is not to be registered for finalization |
221 |
239 |
222 CALLTYPE_API := %{ __MKSMALLINT(__EXTL_CALLTYPE_API) %}. "/ WINAPI-call (win32 only) |
240 CALLTYPE_API := %{ __MKSMALLINT(__EXTL_CALLTYPE_API) %}. "/ WINAPI-call (win32 only) |
820 ^ self invokeFFIwithArguments:arguments forCPPInstance:nil |
852 ^ self invokeFFIwithArguments:arguments forCPPInstance:nil |
821 |
853 |
822 "Modified: / 01-08-2006 / 13:55:35 / cg" |
854 "Modified: / 01-08-2006 / 13:55:35 / cg" |
823 ! |
855 ! |
824 |
856 |
825 invokeFFIwithArguments:argumentsOrNil forCPPInstance:aCPlusPlusObjectOrNil |
857 invokeFFIwithArguments:argumentsOrNil forCPPInstance:aReceiverOrNil |
|
858 "basic invoke mechanism. Calls the function represented by the receiver with argumentsOrNil. |
|
859 For cplusplus, aReceiverOrNil is required to be an externalStructure like object; |
|
860 for objectiveC, it must be an ObjectiveC object" |
|
861 |
826 |argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset |
862 |argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset |
827 virtual async unlimitedStack callTypeNumber returnValueClass argValueClass |
863 virtual objectiveC async unlimitedStack callTypeNumber returnValueClass argValueClass |
828 oldReturnType oldArgumentTypes |
864 oldReturnType oldArgumentTypes| |
829 | |
|
830 |
865 |
831 argTypeSymbols := argumentTypes. |
866 argTypeSymbols := argumentTypes. |
832 returnTypeSymbol := returnType. |
867 returnTypeSymbol := returnType. |
833 |
868 |
834 virtual := self isVirtualCPP. |
869 virtual := self isVirtualCPP. |
|
870 objectiveC := self isObjectiveC. |
835 (virtual "or:[self isNonVirtualCPP]") ifTrue:[ |
871 (virtual "or:[self isNonVirtualCPP]") ifTrue:[ |
836 aCPlusPlusObjectOrNil isNil ifTrue:[ |
872 aReceiverOrNil isNil ifTrue:[ |
837 "/ must have a c++ object instance |
873 "/ must have a c++ object instance |
838 self primitiveFailed. |
874 self primitiveFailed. |
839 ]. |
875 ]. |
840 |
876 |
841 "/ and it must be a kind of ExternalStructure !! |
877 "/ and it must be a kind of ExternalStructure !! |
842 (aCPlusPlusObjectOrNil isKindOf:ExternalStructure) ifFalse:[ |
878 (aReceiverOrNil isKindOf:ExternalStructure) ifFalse:[ |
843 self primitiveFailed. |
879 self primitiveFailed. |
844 ]. |
880 ]. |
845 virtual ifTrue:[ |
881 virtual ifTrue:[ |
846 vtOffset := name. |
882 vtOffset := name. |
847 (vtOffset between:0 and:10000) ifFalse:[ |
883 (vtOffset between:0 and:10000) ifFalse:[ |
848 self primitiveFailed. |
884 self primitiveFailed. |
849 ] |
885 ] |
850 ]. |
886 ]. |
851 ] ifFalse:[ |
887 ] ifFalse:[ |
852 aCPlusPlusObjectOrNil notNil ifTrue:[ |
888 objectiveC ifTrue:[ |
853 "/ must NOT have a c++ object instance |
889 aReceiverOrNil isNil ifTrue:[ |
854 self primitiveFailed. |
890 "/ must have an objective-c object instance |
|
891 self primitiveFailed. |
|
892 ]. |
|
893 (aReceiverOrNil isObjectiveCObject) ifFalse:[ |
|
894 self primitiveFailed |
|
895 ] |
|
896 ] ifFalse:[ |
|
897 aReceiverOrNil notNil ifTrue:[ |
|
898 "/ must NOT have a c++/objectiveC object instance |
|
899 self primitiveFailed. |
|
900 ] |
855 ]. |
901 ]. |
856 ]. |
902 ]. |
857 async := self isAsync. |
903 async := self isAsync. |
858 unlimitedStack := self isUnlimitedStack. |
904 unlimitedStack := self isUnlimitedStack. |
859 callTypeNumber := self callTypeNumber. |
905 callTypeNumber := self callTypeNumber. |
860 "/ Transcript show:name; show:' async:'; showCR:async. |
906 "/ Transcript show:name; show:' async:'; showCR:async. |
861 |
907 |
862 %{ /* STACK: 100000 */ |
908 %{ /* STACK: 100000 */ |
|
909 |
863 #ifdef HAVE_FFI |
910 #ifdef HAVE_FFI |
864 # ifdef __GNUC__ |
911 # ifdef __GNUC__ |
865 # define HAS_LONGLONG |
912 # ifndef HAS_LONGLONG |
|
913 # define HAS_LONGLONG |
|
914 # endif |
866 # endif |
915 # endif |
867 # if defined(__BORLANDC__) || defined(__VISUALC__) |
916 # if defined(__BORLANDC__) || defined(__VISUALC__) |
868 # define HAS_INT64 |
917 # define HAS_INT64 |
869 # endif |
918 # endif |
870 |
919 |
1021 } |
1070 } |
1022 |
1071 |
1023 /* |
1072 /* |
1024 * validate the c++ object |
1073 * validate the c++ object |
1025 */ |
1074 */ |
1026 if (aCPlusPlusObjectOrNil != nil) { |
1075 if (aReceiverOrNil != nil) { |
1027 struct cPlusPlusInstance { |
1076 struct cPlusPlusInstance { |
1028 void **vTable; |
1077 void **vTable; |
1029 }; |
1078 }; |
1030 struct cPlusPlusInstance *inst; |
1079 struct cPlusPlusInstance *inst; |
1031 |
1080 |
1032 if (__isExternalAddressLike(aCPlusPlusObjectOrNil)) { |
1081 if (__isExternalAddressLike(aReceiverOrNil)) { |
1033 inst = (void *)(__externalAddressVal(aCPlusPlusObjectOrNil)); |
1082 inst = (void *)(__externalAddressVal(aReceiverOrNil)); |
1034 } else if (__isExternalBytesLike(aCPlusPlusObjectOrNil)) { |
1083 } else if (__isExternalBytesLike(aReceiverOrNil)) { |
1035 inst = (void *)(__externalBytesVal(aCPlusPlusObjectOrNil)); |
1084 inst = (void *)(__externalBytesVal(aReceiverOrNil)); |
1036 } else { |
1085 } else { |
1037 __FAIL__(@symbol(InvalidInstance)) |
1086 __FAIL__(@symbol(InvalidInstance)) |
1038 } |
1087 } |
1039 __argValues[0].pointerVal = inst; |
1088 __argValues[0].pointerVal = inst; |
1040 __argValuePointersIncludingThis[0] = &(__argValues[0]); |
1089 __argValuePointersIncludingThis[0] = &(__argValues[0]); |
1563 |
1612 |
1564 "Created: / 01-08-2006 / 13:56:23 / cg" |
1613 "Created: / 01-08-2006 / 13:56:23 / cg" |
1565 "Modified: / 11-06-2007 / 01:50:36 / cg" |
1614 "Modified: / 11-06-2007 / 01:50:36 / cg" |
1566 ! |
1615 ! |
1567 |
1616 |
1568 tryAgainWithAsyncSafeArguments:argumentsOrNil forCPPInstance:aCPlusPlusObjectOrNil |
1617 tryAgainWithAsyncSafeArguments:argumentsOrNil forCPPInstance:aReceiverOrNil |
1569 "invoked by the call primitive, iff GC-unsave arguments where passed to the call. |
1618 "invoked by the call primitive, iff GC-unsave arguments where passed to the call. |
1570 Here, allocate non-movable blocks of memory and copy the arguments into them, |
1619 Here, allocate non-movable blocks of memory and copy the arguments into them, |
1571 then try the call again, copy changed values back, and release the memeory." |
1620 then try the call again, copy changed values back, and release the memeory." |
1572 |
1621 |
1573 |saveArguments anyBadArg result originalToSaveArgMapping| |
1622 |saveArguments anyBadArg result originalToSaveArgMapping| |