[squeak-dev] FFI (Plugin) | Question about multi-dimensional arrays (e.g., char**, int**, void*****...)

Jakob Reschke forums.jakob at resfarm.de
Sun Jun 14 19:13:56 UTC 2020

Hi Marcel,

Do you think that the dimensions are always known? I understood that you
also need to know the cardinality per dimension of the involved arrays. If
you want to remember only the number of dimensions, some of my remarks may
not apply. Note that an int** is not a two-dimensional array int[x][y], so
it might be misleading to speak of dimensions. From practice I know we
would need to support at least three pointer indirections, not only two, at
least if you don't want to require intermediate type aliases for pointers
in some cases. See below.

Look at the CredRead function and CREDENTIALS struct for example:

The CredRead function takes essentially a CREDENTIAL** as an output
parameter, so it will give you (dereferencing the passed argument) one
CREDENTIAL*. It is like passing a PCREDENTIAL[1] variable, but you could
well pass it a PCREDENTIAL[6] if you like, since both decay to PCREDENTIAL*
when passed as arguments. Anyway, this is not a two-dimensional array of

For more fun, consider CredEnum:
It takes a CREDENTIAL*** to give you back an array of pointers to
CREDENTIAL structs. How many there are, you will only learn by
dereferencing the count argument. The actual CREDENTIAL structures /could/
be laid out as a CREDENTIAL[count] array, but they don't need to be
(implementation detail). So there is a one-dimensional array of pointers,
there could be, but needn't be, a one-dimensional array of CREDENTIALs, but
certainly there are no two- or three-dimensional arrays here.

Kind regards,

Am So., 14. Juni 2020 um 18:19 Uhr schrieb Marcel Taeumel <
marcel.taeumel at hpi.de>:

> Hi all!
> For some days now, I am thinking about "pointer-to-pointer" types. I
> suppose that the more general topic is the interpretation of
> multi-dimensional arrays.
> On the one hand, this is an in-image issue to correctly read ExternalData
> and to generate appropriate accessors for struct fields.
> On the other hand, this may affect FFI call's arg coercing and return-type
> packaging.
> So, after playing around with an implementation of pointer-to-pointer
> types via ExternalType's #referencedType (i.e. making it a chain of three:
> ... -> void -> void* -> void** -> void ...), I figured that we might need
> to store the array dimensions in the compiledSpec.
> Here are some unused bits for that:
> FFIFlagPointerArrayMask := 16rF00000. "up to 16-dimensional arrays"
> FFIFlagPointerArrayShift := 20.
> Here are some questions for you on this topic:
> - Should we reserve all 4 bits? 16-dimensional arrays sound like overkill
> ... 2 bits could be enough, having rarely the lower one set for char** ...
> - In the image, would you store all possible versions through
> refrencedType in a linked cycle? Or would you lazily create them ... on the
> fly? As requested from struct fields and FFI call specs via ExternalType
> class >> #typeNamed: ?
> - In the FFI plugin, do you see value in coercing an array of, for
> example, IntegerArrays for an FFI call? (int**)
> - In the FFI plugin, do you see value in automatically packaging returned
> objects if those dimensions would be zero-terminated?
> Best,
> Marcel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200614/807802c6/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 15519 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200614/807802c6/attachment.png>

More information about the Squeak-dev mailing list