[squeak-dev] Alien structural change

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Alien structural change

johnmci
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
=
=
=
========================================================================




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Alien structural change

Eliot Miranda-2
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
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
===========================================================================