Support for LP64 & LLP64 in FFI Kernel

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

Support for LP64 & LLP64 in FFI Kernel

Eliot Miranda-2
Hi All,

    currently the FFI has support for 8, 16, 32 & 64 bit integers, but no support for C's long type.  In almost all C implementations byte is 8 bits, short is 16 bits, int is 32 bits and long long is 64 bits.  But long may be either 32 or 64 bits depending on programming model.

In LP32 long is 32 bits, which is used in 32-bit unix, mac os and windows.
In LP64 long is 64 bits, which is used in 64-bit unix and mac os.
In LLP64 long is 32 bits, which is used in 64-bit windows.

So having a type which is either 32 or 64 bits depending on platform is useful in modeling C's long type across platforms.  Esteban and I propose adding such a type to FFI kernel, actually two types, one unsigned, one signed.  So we propose extending the below (these constants are used to define signatures for FFI calls and the contents of structs)

FFIConstants class>>#initializeTypeConstants
"type void"
FFITypeVoid := 0.

"type bool"
FFITypeBool := 1.

"basic integer types.
note: (integerType anyMask: 1) = integerType isSigned"

FFITypeUnsignedByte := 2.
FFITypeSignedByte := 3.
FFITypeUnsignedShort := 4.
FFITypeSignedShort := 5.
FFITypeUnsignedInt := 6.
FFITypeSignedInt := 7.

"64bit types"
FFITypeUnsignedLongLong := 8.
FFITypeSignedLongLong := 9.

"special integer types"
FFITypeUnsignedChar := 10.
FFITypeSignedChar := 11.

"float types"
FFITypeSingleFloat := 12.
FFITypeDoubleFloat := 13.

"type flags"
FFIFlagAtomic := 16r40000. "type is atomic"
FFIFlagPointer := 16r20000. "type is pointer to base type"
FFIFlagStructure := 16r10000. "baseType is structure of 64k length"
FFIStructSizeMask := 16rFFFF. "mask for max size of structure"
FFIAtomicTypeMask := 16r0F000000. "mask for atomic type spec"
FFIAtomicTypeShift := 24. "shift for atomic type"

to add to
"special integer types"
FFITypeUnsignedChar := 10.
FFITypeSignedChar := 11.
FFITypePlatformUnsignedLong := 14.
FFITypePlatformSignedLong := 15.

This is backward compatible, even if it complicates the marshaling a little since it used to be that all integer types were less than FFITypeSingleFloat.  But breaking backward compatibility would be a bad idea.

Then in ByteArray et al we could add accessors for platformLongAt: platformUnsignedLongAt:.

Comments, thoughts, objections?
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Support for LP64 & LLP64 in FFI Kernel

David T. Lewis
+1
This sounds like a good approach to me.

Dave

> Hi All,
>
>     currently the FFI has support for 8, 16, 32 & 64 bit integers, but no
> support for C's long type.  In almost all C implementations byte is 8
> bits,
> short is 16 bits, int is 32 bits and long long is 64 bits.  But long may
> be
> either 32 or 64 bits depending on programming model.
>
> In LP32 long is 32 bits, which is used in 32-bit unix, mac os and windows.
> In LP64 long is 64 bits, which is used in 64-bit unix and mac os.
> In LLP64 long is 32 bits, which is used in 64-bit windows.
>
> So having a type which is either 32 or 64 bits depending on platform is
> useful in modeling C's long type across platforms.  Esteban and I propose
> adding such a type to FFI kernel, actually two types, one unsigned, one
> signed.  So we propose extending the below (these constants are used to
> define signatures for FFI calls and the contents of structs)
>
> FFIConstants class>>#initializeTypeConstants
> "type void"
> FFITypeVoid := 0.
>
> "type bool"
> FFITypeBool := 1.
>
> "basic integer types.
> note: (integerType anyMask: 1) = integerType isSigned"
>
> FFITypeUnsignedByte := 2.
> FFITypeSignedByte := 3.
> FFITypeUnsignedShort := 4.
> FFITypeSignedShort := 5.
> FFITypeUnsignedInt := 6.
> FFITypeSignedInt := 7.
>
> "64bit types"
> FFITypeUnsignedLongLong := 8.
> FFITypeSignedLongLong := 9.
>
> "special integer types"
> FFITypeUnsignedChar := 10.
> FFITypeSignedChar := 11.
>
> "float types"
> FFITypeSingleFloat := 12.
> FFITypeDoubleFloat := 13.
>
> "type flags"
> FFIFlagAtomic := 16r40000. "type is atomic"
> FFIFlagPointer := 16r20000. "type is pointer to base type"
> FFIFlagStructure := 16r10000. "baseType is structure of 64k length"
> FFIStructSizeMask := 16rFFFF. "mask for max size of structure"
> FFIAtomicTypeMask := 16r0F000000. "mask for atomic type spec"
> FFIAtomicTypeShift := 24. "shift for atomic type"
>
> to add to
> "special integer types"
> FFITypeUnsignedChar := 10.
> FFITypeSignedChar := 11.
> FFITypePlatformUnsignedLong := 14.
> FFITypePlatformSignedLong := 15.
>
> This is backward compatible, even if it complicates the marshaling a
> little
> since it used to be that all integer types were less than
> FFITypeSingleFloat.  But breaking backward compatibility would be a bad
> idea.
>
> Then in ByteArray et al we could add accessors for platformLongAt:
> platformUnsignedLongAt:.
>
> Comments, thoughts, objections?
> _,,,^..^,,,_
> best, Eliot
>
>