For the very few folks that are working with Alien I'm about to make a
structural change that is needed to support floating point arguments on PowerPC. Because of how the os-x powerpc abi works we *do* need to know what type the parameters are in order to decide if that 32bit data item is a float or long, or if 64bit a long long or double. Parms are passed based on if they are Floating point or non-floating point. This is a bit of a pain because MacIntel users still can pass integer, float, long long, double without regard to typing, yet if they expect to run on PowerPC a bit more care and typing is required. In the example below the primFFICallResult:with:with: call has no idea if the alien 1 or alien 2 are long long or double. testCallingSquenceLongLong2 | alien1 alien2 result who | alien1 := Alien newC: 8. alien2 := Alien newC: 8. alien1 signedLongLongAt: 1 put: 1. alien2 signedLongLongAt: 1 put: 42. er or is that alien1 doubleAt: 1 put: 1. alien2 doubleAt: 1 put: 42. who := Alien lookup: 'ffiTestLongLong' inLibrary: 'IA32ABI'. result := who primFFICallResult: (Alien new: 8) with: alien1 with: alien2. self should: [(result signedLongLongAt: 1) = (1+42)]. alien1 free. alien2 free. In talking to Eliot we feel this will become for Double who primFFICallResultWithFloatParms: (Alien new: 8) with: alien1 with: alien2. with: (ByteArray with: 8 with: 8) for Float who primFFICallResultWithFloatParms: (Alien new: 8) with: alien1 with: alien2. with: (ByteArray with: 4 with: 4) The last parm is a tag array that contains information about the size of the floating point object. Now in order to cheat a bit here we will allow you to say who primFFICallResult: (Alien new: 8) with: 1.0 with: 42.0. because we know the element being passed is a floating point squeak object so we will assume we should treat it as a Double parm. This of course won't work very well if you are dealing with a Float so you would need to use the who primFFICallResultWithFloatParms: (Alien new: 8) with: 1.0 with: 42.0. with: (ByteArray with: 4 with: 4) Remember if you do: who primFFICallResult: (Alien new: 8) with: oneParm with: twoParm. where oneParm/twoParm is *usually* a float you really need to take care and say who primFFICallResult: (Alien new: 8) with: oneParm asFloat with: twoParm asFloat. Lastly if you do who primFFICallResultWithFloatParms: (Alien new: 8) with: 1 with: 42. with: (ByteArray with: 4 with: 4) The we'll assume oneParm and twoParm are floats and not do any autoconversion if say you pass an integer and your results will be unexpected, or trigger an primitive failure. -- = = = ======================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com = = = ======================================================================== |
John, I'd write it like this
who primFFICallResult: (Alien new: 8) floatParmsSignature: (ByteArray with: 8 with: 8) with: alien1 with: alien2. I'd also modify the compiler so that, like VW, #[8 8] is a literal ByteArray equal to (ByteArray with: 8 with: 8).
If floatParmsSignature is nil that is equivalent to passing a ByteArray with all 0's. I'd also make sure that the signature byte array only has to be long enough, i.e. if there are more parameters than the signature byte array then their type is effectively 0.
On Thu, Dec 11, 2008 at 12:32 PM, John M McIntosh <[hidden email]> wrote: For the very few folks that are working with Alien I'm about to make a structural change that is |
Free forum by Nabble | Edit this page |