[Vm-dev] Request for changing auto-generated accessors of FFI aliases

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Mon Apr 16 19:39:15 UTC 2018


Hi,
the title is a bit complex, but I'll try to explain what I am after.

I need to pass a pointer to an atomic data because it is an output of a
function.
But this atomic data is a named type (a typedef), and I want to preserve
the name for several reasons:
- the typedef might evolve in another version of the library
- the typedef might be machine dependent (like size_t or unsigned long)

In VW, it's simple enough, i define the typedef directly, then use malloc
and free like this:

H5Type>>getPadding
    | lsb msb |
    [lsb := API H5T_pad_t malloc.
    msb := API H5T_pad_t malloc.
    API H5Tget_pad: handle with: lsb with: msb.
    lsbPadCache := lsb contents.
    msbPadCache := msb contents]
            ensure:
                [lsb isNil ifFalse: [lsb free].
                msb isNil ifFalse: [msb free]]

H5T_pad_t
    <C: typedef enum __H5T_pad_t H5T_pad_t>

H5Interface>>H5Tget_pad: type_id with: lsb with: msb
    <C: herr_t H5Tget_pad(hid_t type_id, H5T_pad_t * lsb, H5T_pad_t * msb)>
    ^self externalAccessFailedWith: _errorCode

In Squeak, I have used this feature of ExternalStructure so as to alias
another type (and have a sort of typedef):

https://stackoverflow.com/questions/49783882/how-one-deals-with-typedefs-in-squeak-ffi/49798663#49798663

So I create the class:

ExternalStructure subclass: #'H5T_pad_t'
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'FFI-Tests'

Since it is an enum, I can use methods for accessing enum values

H5T_pad_t class>>H5T_PAD_ERROR ^-1
H5T_pad_t class>>H5T_PAD_ZERO  ^0
H5T_pad_t class>>H5T_PAD_ONE   ^1
H5T_pad_t class>>H5T_PAD_BACKGROUND ^2
H5T_pad_t class>>H5T_NPAD      ^3

And I can define the fields with the knowledge that most C implementation
will use an int to store the enum:

H5T_pad_t class>>fields ^#( value 'long')

Then I can generate #value and #value: via H5T_pad_t defineFields and write:

H5Type>>getPadding
    | lsb msb |
    lsb := H5T_pad_t new.
    msb := H5T_pad_t new.
    API H5Tget_pad: handle with: lsb with: msb.
    lsbPadCache := lsb value.
    msbPadCache := msb value

H5Interface>>H5Tget_pad: type_id with: lsb with: msb
    <cdecl: Herr_t 'H5Tget_pad'( Hid_t H5T_pad_t * H5T_pad_t * )>
    ^self externalCallFailed

H5T_pad_t new does the right thing: it allocates memory in a ByteArray, and
store it in handle inst. var., something like handle := ByteArray new: 4

But then, the generated accessors not so: they consider that a non pointer
atomic type does not require an intermediate memory buffer, because FFI can
transform directly a Smalltalk atomic object
(Integer/Boolean/Character/Float).

    value  ^handle
    value: anObject handle := anObject

They return the buffer instead of the content.

This is completely missing the point: the only reason I have to create an
instance of such atomic type is to pass a reference (pointer) to the data,
else, I can just use one of the enum accessors and pass the integer value
directly:

H5TInteger>>setPadZero
    API H5Tset_pad: handle with: H5T_pad_t H5T_PAD_ZERO with: H5T_pad_t
H5T_PAD_ZERO

H5Interface>>H5Tset_pad: type_id with: lsb with: msb
    <cdecl: Herr_t 'H5Tset_pad'( Hid_t H5T_pad_t H5T_pad_t )>
    ^self externalCallFailed

what I want is this:

    value ^handle longAt: 1
    value: anObject  handle longAt: 1 put: anObject

It's very simple to change because such generation already exists for
accessing structure fields.

It's very logical to change, because consistent with the behavior of new
and possible intentions of allocating an instance of such type as I showed
above.

However, I absolutely don't know the impact of such change on existing code
base.

1) the alias feature is not documented, has no test and no example (with
accessors)
2) I don't know an easy way to scan the existing code base
   (SqueakSource, ss3, SmalltalkHub, HPI, etc...)

Has anyone got a better idea, or knows a library that would be broken, or
have a strong opinion against this change for whatever reason?

I'll understand the absence of answer as a "carte blanche" to proceed.

Nicolas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20180416/e773867c/attachment-0001.html>


More information about the Vm-dev mailing list