--- a/ExternalLibraryFunction.st Fri Aug 11 11:06:50 2006 +0200
+++ b/ExternalLibraryFunction.st Fri Aug 11 12:27:28 2006 +0200
@@ -516,7 +516,7 @@
invokeFFIwithArguments:arguments forCPPInstance:aCPlusPlusObjectOrNil
|argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset
- virtual async unlimitedStack callTypeNumber|
+ virtual async unlimitedStack callTypeNumber returnValueClass argValueClass|
argumentTypes notNil ifTrue:[
argTypeSymbols := argumentTypes collect:[:argType | self ffiTypeSymbolForType:argType].
@@ -524,7 +524,7 @@
returnTypeSymbol := self ffiTypeSymbolForType:returnType.
virtual := self isVirtualCPP.
- (virtual or:[self isNonVirtualCPP]) ifTrue:[
+ (virtual "or:[self isNonVirtualCPP]") ifTrue:[
aCPlusPlusObjectOrNil isNil ifTrue:[
"/ must have a c++ object instance
self primitiveFailed.
@@ -671,8 +671,22 @@
} else if (returnTypeSymbol == @symbol(wcharPointer)) {
__returnType = __get_ffi_type_pointer();
} else {
- failureCode = @symbol(UnknownReturnType);
- goto getOutOfHere;
+ if (__isSymbol(returnTypeSymbol)
+ && ((returnValueClass = __GLOBAL_GET(returnTypeSymbol)) != nil)) {
+ if (! __isBehaviorLike(returnValueClass)) {
+ failureCode = @symbol(NonBehaviorReturnType);
+ goto getOutOfHere;
+ }
+ if (! __qIsSubclassOfExternalAddress(returnValueClass)) {
+ failureCode = @symbol(NonExternalAddressReturnType);
+ goto getOutOfHere;
+ }
+ __returnType = __get_ffi_type_pointer();
+ returnTypeSymbol = @symbol(pointer);
+ } else {
+ failureCode = @symbol(UnknownReturnType);
+ goto getOutOfHere;
+ }
}
/*
@@ -713,6 +727,9 @@
}
} else {
__numArgsIncludingThis = __numArgs;
+#ifdef VERBOSE
+ printf("codeAddress: %x\n", codeAddress);
+#endif
}
/*
@@ -903,6 +920,7 @@
argValuePtr = &(__argValues[i].pointerVal);;
} else if (typeSymbol == @symbol(pointer)) {
+commonPointerTypeArg: ;
thisType = __get_ffi_type_pointer();
if (arg == nil) {
__argValues[i].pointerVal = NULL;
@@ -913,9 +931,6 @@
} else if (__isByteArray(arg)) {
if (async == true) goto badArgForAsyncCall;
__argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
- } else if (__isByteArray(arg)) {
- if (async == true) goto badArgForAsyncCall;
- __argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
} else if (__isFloatArray(arg)) {
if (async == true) goto badArgForAsyncCall;
__argValues[i].pointerVal = (void *)(__FloatArrayInstPtr(arg)->f_element);
@@ -961,14 +976,29 @@
}
argValuePtr = &(__argValues[i].iVal);
} else {
- failureCode = @symbol(UnknownArgumentType);
- goto getOutOfHere;
+ if (__isSymbol(typeSymbol)
+ && ((argValueClass = __GLOBAL_GET(typeSymbol)) != nil)) {
+ if (! __isBehaviorLike(argValueClass)) {
+ failureCode = @symbol(NonBehaviorArgumentType);
+ goto getOutOfHere;
+ }
+ if (! __qIsSubclassOfExternalAddress(argValueClass)) {
+ failureCode = @symbol(NonExternalAddressArgumentType);
+ goto getOutOfHere;
+ }
+ goto commonPointerTypeArg; /* sorry */
+ } else {
+ failureCode = @symbol(UnknownArgumentType);
+ goto getOutOfHere;
+ }
}
__argTypes[i] = thisType;
__argValuePointers[i] = argValuePtr;
+#ifdef VERBOSE
printf("arg%d: %x\n", i, __argValues[i].iVal);
+#endif
}
failureInfo = nil;
@@ -1000,6 +1030,9 @@
goto getOutOfHere;
}
if (async == true) {
+#ifdef VERBOSE
+ printf("async call 0x%x\n", codeAddress);
+#endif
#ifdef WIN32
__STX_C_CALL4( "ffi_call", ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
#else
@@ -1009,14 +1042,22 @@
#endif
} else {
if (unlimitedStack == true) {
+#ifdef VERBOSE
+ printf("UNLIMITEDSTACKCALL call 0x%x\n", codeAddress);
+#endif
#if 0
__UNLIMITEDSTACKCALL__(ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
#endif
} else {
+#ifdef VERBOSE
+ printf("call 0x%x\n", codeAddress);
+#endif
ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
}
}
-printf("retval is %d (0x%x)\n", __returnValue.iVal, __returnValue.iVal);
+#ifdef VERBOSE
+ printf("retval is %d (0x%x)\n", __returnValue.iVal, __returnValue.iVal);
+#endif
if ((returnTypeSymbol == @symbol(sint))
|| (returnTypeSymbol == @symbol(sint8))
|| (returnTypeSymbol == @symbol(sint16))
@@ -1070,6 +1111,9 @@
].
returnType isSymbol ifTrue:[
+ returnValueClass notNil ifTrue:[
+ returnValue changeClassTo:returnValueClass
+ ].
] ifFalse:[
returnType isCPointer ifTrue:[
returnType baseType isCStruct ifTrue:[
@@ -1093,7 +1137,7 @@
!ExternalLibraryFunction class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.40 2006-08-11 08:56:53 ca Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.41 2006-08-11 10:27:28 ca Exp $'
! !
ExternalLibraryFunction initialize!