[squeak-dev] [Vm-dev] 64 bit FFI (was: porting Croquet to Squeak6.0 alpha...)

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Mar 18 13:45:41 UTC 2020

Well, we have void *, it's opaque enough.
In this case, the storage area must be allocated on heap by some foreign
function, and a pointer to it passed back as handle.
The problem with void * is that it is not specific enough.
We thus generally create a type alias. A type alias is a subclass of
ExternalStructure. As such, the class name can be used as a type
specification in external function interface.
An aliased type differs from a regular struct by the fields definition at
class side.
While structure has fields made of an array of pairs #( #(memberName
ffiType) ),  an aliased type as a single array #( nil ffiType ).
Using nil avoids creating an accessor. The ffiType can be an integer large
enough to hold a pointer (intptr_t, but we do not support that in FFI) -
See WinHandle in the FFI-Win32 examples - or 'void *' (I think it may work,
but it's a long time since I did not test).

Le jeu. 12 mars 2020 à 15:21, Jakob Reschke <forums.jakob at resfarm.de> a
écrit :

> Would it be possible to include an opaque "pointer" basic type in the FFI,
> to prevent reinventing the wheel in each project? It should reshape
> accordingly with the platform. If not possible, what are the hurdles?
> Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com> schrieb am Do., 12.
> März 2020, 13:21:
>> Hi all,
>> beware of FFI 'long' and 'ulong'.
>> They are currently meaning (32 bits) int and unsigned int!
>> This dates back from the 80s when there were still odd OS with segmented
>> memory and 16-bits int.
>> long was thought as a safe int32_t at that time... and still means just
>> that in current FFI.
>> I'd like to replace them with 'int' and 'uint', but we need to ensure
>> backward compatibility etc...
>> FFI has ExternalType signedLongLong or just 'longlong' and ExternalType
>> unsignedLongLong or 'ulonglong' which are 64 bits on all architectures.
>> See implementors of #initializeAtomicTypes #initializeFFIConstants
>> If you want a type that can hold a pointer on both 32 and 64bits arch,
>> then it's doable with a FFI type alias
>> For example I have things like this in HDF5 module
>> Notice the single #(fieldName fieldType) which defines an alias, while
>> ordinary FFI struct gets an array of #(fieldName fieldType)
>> (and replace Size_t with Intptr_t if the purpose is hodling a pointer,
>> otherwise the ayatollahs of C standard will lash you)
>> ExternalStructure subclass: #'Size_t'
>>     instanceVariableNames: ''
>>     classVariableNames: ''
>>     poolDictionaries: ''
>>     category: 'HDF5-External-atomic'
>> Size_t class >>fields
>>     "Size_t defineFields"
>>     ^Smalltalk wordSize = 4
>>         ifTrue: [#( value 'ulong')]
>>         ifFalse: [#( value 'ulonglong')]
>> However the "fields" must be re-generated when platform changes...
>> I tried to automate that sometimes ago, see:
>> ExternalStructure class>>install
>>      "Resuming the image on another architecture may require a
>> re-compilation of structure layout."
>>      | newPlatform |
>>      newPlatform := Smalltalk platformName.
>>      PreviousPlatform = newPlatform
>>          ifFalse:
>>              [self recompileStructures.
>>             PreviousPlatform := newPlatform]
>> It works if you switch from Win64 to MacOS64 for example...
>> However, this mechanism is not used yet at time of code loading, so
>> importing code generated on a different platform won't automatically update
>> the structures (or alias) - the FFI package has no mechanism for that
>> (maybe we could add a hook in MC?).
>> Le mer. 11 mars 2020 à 23:58, Bert Freudenberg <bert at freudenbergs.de> a
>> écrit :
>>> I'd suggest to get OpenGL working outside of Croquet first:
>>> http://www.squeaksource.com/CroquetGL.html
>>> Step 1: Verify this works in 32 bits. (assuming you are doing this on
>>> Linux, you can run 32 bit Squeak side-by-side with the 64 bit one)
>>> Step 2: Make it work in 64 bits.
>>> The second step requires that you understand how FFI works, and how it
>>> handles e.g. pointers and integer sizes.
>>> I am assuming we do have a working 64 bit FFI, at least for x86_64
>>> machines.
>>> E.g. the OGLUnix>>glExtGetProcAddress: method returns a pointer. On a
>>> 32 bit system, that fits into a 'ulong' which is 32 bits. On a 64 bit
>>> system, a pointer is 64 bits wide so it would not fit into a 32 bit word.
>>> Now I don't know how many bits 'ulong' has in our 64 bit FFI, but that
>>> declaration may have to change. Etc. pp.
>>> If you have questions about FFI then those are best directed at the
>>> vm-dev list since it is dealing with VM-level interfaces. CC'ing, please
>>> follow up there.
>>> - Bert -
>>> On Wed, Mar 11, 2020 at 2:54 PM gettimothy via Squeak-dev <
>>> squeak-dev at lists.squeakfoundation.org> wrote:
>>>> Okey dokey,
>>>> Poking along, there is a stray glyph in OGLUnix openGLLibraryName after
>>>> openGLLibraryName
>>>> ^Smalltalk osVersion = 'linux'
>>>> ifTrue: ['libGL.so.1']
>>>> ifFalse: ['GL']
>>>> I removed it in my install and got past that error.
>>>> Working exclusively with Croquet(Master)...
>>>> My next error is in OGLUnixX11LE(OpenGL)>>glMatrixMode:
>>>> glMatrixMode: mode
>>>> "This method was automatically generated."
>>>> "void glMatrixMode(GLenum mode);"
>>>> <apicall: void 'glMatrixMode' (ulong) module: '#openGLLibraryName'>
>>>> ^self externalCallFailed
>>>> The <apicall:...> fails
>>>> How to think about this?
>>>> Is Croquet behind OpenGL latest?
>>>> Would teaching myself OpenGL programming be of use to the Croquet
>>>> project?
>>>> cheers,
>>>> tty
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200318/d62b15f2/attachment.html>

More information about the Squeak-dev mailing list