514 "Modified: / 01-08-2006 / 13:55:35 / cg" |
514 "Modified: / 01-08-2006 / 13:55:35 / cg" |
515 ! |
515 ! |
516 |
516 |
517 invokeFFIwithArguments:arguments forCPPInstance:aCPlusPlusObjectOrNil |
517 invokeFFIwithArguments:arguments forCPPInstance:aCPlusPlusObjectOrNil |
518 |argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset |
518 |argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset |
519 virtual async unlimitedStack callTypeNumber| |
519 virtual async unlimitedStack callTypeNumber returnValueClass argValueClass| |
520 |
520 |
521 argumentTypes notNil ifTrue:[ |
521 argumentTypes notNil ifTrue:[ |
522 argTypeSymbols := argumentTypes collect:[:argType | self ffiTypeSymbolForType:argType]. |
522 argTypeSymbols := argumentTypes collect:[:argType | self ffiTypeSymbolForType:argType]. |
523 ]. |
523 ]. |
524 returnTypeSymbol := self ffiTypeSymbolForType:returnType. |
524 returnTypeSymbol := self ffiTypeSymbolForType:returnType. |
525 |
525 |
526 virtual := self isVirtualCPP. |
526 virtual := self isVirtualCPP. |
527 (virtual or:[self isNonVirtualCPP]) ifTrue:[ |
527 (virtual "or:[self isNonVirtualCPP]") ifTrue:[ |
528 aCPlusPlusObjectOrNil isNil ifTrue:[ |
528 aCPlusPlusObjectOrNil isNil ifTrue:[ |
529 "/ must have a c++ object instance |
529 "/ must have a c++ object instance |
530 self primitiveFailed. |
530 self primitiveFailed. |
531 ]. |
531 ]. |
532 |
532 |
669 } else if (returnTypeSymbol == @symbol(charPointer)) { |
669 } else if (returnTypeSymbol == @symbol(charPointer)) { |
670 __returnType = __get_ffi_type_pointer(); |
670 __returnType = __get_ffi_type_pointer(); |
671 } else if (returnTypeSymbol == @symbol(wcharPointer)) { |
671 } else if (returnTypeSymbol == @symbol(wcharPointer)) { |
672 __returnType = __get_ffi_type_pointer(); |
672 __returnType = __get_ffi_type_pointer(); |
673 } else { |
673 } else { |
674 failureCode = @symbol(UnknownReturnType); |
674 if (__isSymbol(returnTypeSymbol) |
675 goto getOutOfHere; |
675 && ((returnValueClass = __GLOBAL_GET(returnTypeSymbol)) != nil)) { |
|
676 if (! __isBehaviorLike(returnValueClass)) { |
|
677 failureCode = @symbol(NonBehaviorReturnType); |
|
678 goto getOutOfHere; |
|
679 } |
|
680 if (! __qIsSubclassOfExternalAddress(returnValueClass)) { |
|
681 failureCode = @symbol(NonExternalAddressReturnType); |
|
682 goto getOutOfHere; |
|
683 } |
|
684 __returnType = __get_ffi_type_pointer(); |
|
685 returnTypeSymbol = @symbol(pointer); |
|
686 } else { |
|
687 failureCode = @symbol(UnknownReturnType); |
|
688 goto getOutOfHere; |
|
689 } |
676 } |
690 } |
677 |
691 |
678 /* |
692 /* |
679 * validate the c++ object |
693 * validate the c++ object |
680 */ |
694 */ |
901 } |
918 } |
902 } |
919 } |
903 argValuePtr = &(__argValues[i].pointerVal);; |
920 argValuePtr = &(__argValues[i].pointerVal);; |
904 |
921 |
905 } else if (typeSymbol == @symbol(pointer)) { |
922 } else if (typeSymbol == @symbol(pointer)) { |
|
923 commonPointerTypeArg: ; |
906 thisType = __get_ffi_type_pointer(); |
924 thisType = __get_ffi_type_pointer(); |
907 if (arg == nil) { |
925 if (arg == nil) { |
908 __argValues[i].pointerVal = NULL; |
926 __argValues[i].pointerVal = NULL; |
909 } else if (__isExternalAddressLike(arg)) { |
927 } else if (__isExternalAddressLike(arg)) { |
910 __argValues[i].pointerVal = (void *)(__externalAddressVal(arg)); |
928 __argValues[i].pointerVal = (void *)(__externalAddressVal(arg)); |
911 } else if (__isExternalBytesLike(arg)) { |
929 } else if (__isExternalBytesLike(arg)) { |
912 __argValues[i].pointerVal = (void *)(__externalBytesVal(arg)); |
930 __argValues[i].pointerVal = (void *)(__externalBytesVal(arg)); |
913 } else if (__isByteArray(arg)) { |
|
914 if (async == true) goto badArgForAsyncCall; |
|
915 __argValues[i].pointerVal = (void *)(__byteArrayVal(arg)); |
|
916 } else if (__isByteArray(arg)) { |
931 } else if (__isByteArray(arg)) { |
917 if (async == true) goto badArgForAsyncCall; |
932 if (async == true) goto badArgForAsyncCall; |
918 __argValues[i].pointerVal = (void *)(__byteArrayVal(arg)); |
933 __argValues[i].pointerVal = (void *)(__byteArrayVal(arg)); |
919 } else if (__isFloatArray(arg)) { |
934 } else if (__isFloatArray(arg)) { |
920 if (async == true) goto badArgForAsyncCall; |
935 if (async == true) goto badArgForAsyncCall; |
959 goto getOutOfHere; |
974 goto getOutOfHere; |
960 } |
975 } |
961 } |
976 } |
962 argValuePtr = &(__argValues[i].iVal); |
977 argValuePtr = &(__argValues[i].iVal); |
963 } else { |
978 } else { |
964 failureCode = @symbol(UnknownArgumentType); |
979 if (__isSymbol(typeSymbol) |
965 goto getOutOfHere; |
980 && ((argValueClass = __GLOBAL_GET(typeSymbol)) != nil)) { |
|
981 if (! __isBehaviorLike(argValueClass)) { |
|
982 failureCode = @symbol(NonBehaviorArgumentType); |
|
983 goto getOutOfHere; |
|
984 } |
|
985 if (! __qIsSubclassOfExternalAddress(argValueClass)) { |
|
986 failureCode = @symbol(NonExternalAddressArgumentType); |
|
987 goto getOutOfHere; |
|
988 } |
|
989 goto commonPointerTypeArg; /* sorry */ |
|
990 } else { |
|
991 failureCode = @symbol(UnknownArgumentType); |
|
992 goto getOutOfHere; |
|
993 } |
966 } |
994 } |
967 |
995 |
968 __argTypes[i] = thisType; |
996 __argTypes[i] = thisType; |
969 __argValuePointers[i] = argValuePtr; |
997 __argValuePointers[i] = argValuePtr; |
970 |
998 |
|
999 #ifdef VERBOSE |
971 printf("arg%d: %x\n", i, __argValues[i].iVal); |
1000 printf("arg%d: %x\n", i, __argValues[i].iVal); |
|
1001 #endif |
972 } |
1002 } |
973 failureInfo = nil; |
1003 failureInfo = nil; |
974 |
1004 |
975 __callType = FFI_DEFAULT_ABI; |
1005 __callType = FFI_DEFAULT_ABI; |
976 |
1006 |
998 if (ffi_prep_cif(&__cif, __callType, __numArgsIncludingThis, __returnType, __argTypesIncludingThis) != FFI_OK) { |
1028 if (ffi_prep_cif(&__cif, __callType, __numArgsIncludingThis, __returnType, __argTypesIncludingThis) != FFI_OK) { |
999 failureCode = @symbol(FFIPrepareFailed); |
1029 failureCode = @symbol(FFIPrepareFailed); |
1000 goto getOutOfHere; |
1030 goto getOutOfHere; |
1001 } |
1031 } |
1002 if (async == true) { |
1032 if (async == true) { |
|
1033 #ifdef VERBOSE |
|
1034 printf("async call 0x%x\n", codeAddress); |
|
1035 #endif |
1003 #ifdef WIN32 |
1036 #ifdef WIN32 |
1004 __STX_C_CALL4( "ffi_call", ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1037 __STX_C_CALL4( "ffi_call", ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1005 #else |
1038 #else |
1006 __BEGIN_INTERRUPTABLE__ |
1039 __BEGIN_INTERRUPTABLE__ |
1007 ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1040 ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1008 __END_INTERRUPTABLE__ |
1041 __END_INTERRUPTABLE__ |
1009 #endif |
1042 #endif |
1010 } else { |
1043 } else { |
1011 if (unlimitedStack == true) { |
1044 if (unlimitedStack == true) { |
|
1045 #ifdef VERBOSE |
|
1046 printf("UNLIMITEDSTACKCALL call 0x%x\n", codeAddress); |
|
1047 #endif |
1012 #if 0 |
1048 #if 0 |
1013 __UNLIMITEDSTACKCALL__(ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1049 __UNLIMITEDSTACKCALL__(ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1014 #endif |
1050 #endif |
1015 } else { |
1051 } else { |
|
1052 #ifdef VERBOSE |
|
1053 printf("call 0x%x\n", codeAddress); |
|
1054 #endif |
1016 ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1055 ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis); |
1017 } |
1056 } |
1018 } |
1057 } |
1019 printf("retval is %d (0x%x)\n", __returnValue.iVal, __returnValue.iVal); |
1058 #ifdef VERBOSE |
|
1059 printf("retval is %d (0x%x)\n", __returnValue.iVal, __returnValue.iVal); |
|
1060 #endif |
1020 if ((returnTypeSymbol == @symbol(sint)) |
1061 if ((returnTypeSymbol == @symbol(sint)) |
1021 || (returnTypeSymbol == @symbol(sint8)) |
1062 || (returnTypeSymbol == @symbol(sint8)) |
1022 || (returnTypeSymbol == @symbol(sint16)) |
1063 || (returnTypeSymbol == @symbol(sint16)) |
1023 || (returnTypeSymbol == @symbol(sint32))) { |
1064 || (returnTypeSymbol == @symbol(sint32))) { |
1024 RETURN ( __MKINT(__returnValue.iVal) ); |
1065 RETURN ( __MKINT(__returnValue.iVal) ); |
1068 self primitiveFailed. |
1109 self primitiveFailed. |
1069 ^ nil |
1110 ^ nil |
1070 ]. |
1111 ]. |
1071 |
1112 |
1072 returnType isSymbol ifTrue:[ |
1113 returnType isSymbol ifTrue:[ |
|
1114 returnValueClass notNil ifTrue:[ |
|
1115 returnValue changeClassTo:returnValueClass |
|
1116 ]. |
1073 ] ifFalse:[ |
1117 ] ifFalse:[ |
1074 returnType isCPointer ifTrue:[ |
1118 returnType isCPointer ifTrue:[ |
1075 returnType baseType isCStruct ifTrue:[ |
1119 returnType baseType isCStruct ifTrue:[ |
1076 stClass := Smalltalk classNamed:returnType baseType name. |
1120 stClass := Smalltalk classNamed:returnType baseType name. |
1077 stClass notNil ifTrue:[ |
1121 stClass notNil ifTrue:[ |