<div dir="ltr">Hi Nicolas,<div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 13, 2018 at 10:53 AM, Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div>So the current algorithm  in #defineFields: and compileFields: is producing compact structures layout with all fields aligned on 1 byte.<br></div><br></div>It does not correspond to any platform behavior except when using special pragmas or compiler options.<br><br></div>The current workaround is to force a length in 3rd column of spec.<br><a href="https://stackoverflow.com/questions/49782651/how-one-aligns-structure-fields-in-squeak-ffi/49782754#49782754" target="_blank">https://stackoverflow.com/<wbr>questions/49782651/how-one-<wbr>aligns-structure-fields-in-<wbr>squeak-ffi/49782754#49782754</a><br></div>But it's brainfuck:<br>- it depends both on the fields preceding and the fields following<br></div><div>- it becomes very hard to support both 32+64 bits<br></div><div><br></div>#(<br>    (x 'char' 2)<br>    (y 'short')<br> )<br>#(<br>    (x 'char' 4) "depends on the field following"<br>    (y 'long')<br> )<br>#(<br>    (w 'char' 1)<br>    (x 'char' 3) "but also on the field preceding"<br>    (y 'long')<br> )<br><br></div>I'd like to make our default behavior match that of the current platform<br></div>- atomic fields of size 1,2,4,8 bytes have alignment = size<br></div><div>- pointers also have alignment = pointer size (4 or 8).<br></div>- nested structures have alignment = max of alignment of their fields<br><br></div>Then we can support exotic alignment with a 4th column in spec:<br><br></div>#( (x 'char' -1 1) (y 'short' -1 1) ) "compact"<br><br></div>The 3rd column -1 or nil would mean<br>"use the default size rather than force a user defined one"<br></div></div></blockquote><div><br></div><div>Agreed.  This looks sane.  AFAIA this fits all our currently supported platforms, right?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Other suggestions?<br></div></div></blockquote></div><br>This isn't another suggestion.  It is more an extension of what you propose.</div><div class="gmail_extra"><br>We could somehow try and maintain 64-bit and 32-bit versions of each type.  Imagine adding an instance variable to ExternalType, say compiledSpecs, which is a dictionary from layout name (#default32, #default64, #dos32, etc) to compiledSpec for that layout.  Then provide a realign method that on start-up selects the correct compiledSpec for the current platform, and if it is different to the type's currentSpec inst var collects instances of the referent class and realigns the contents.</div><div class="gmail_extra"><br></div><div class="gmail_extra">This needs some thought because the accessors are in the referentClass.  If the ExternalType also stored the accessor methods for each field, it could swap these in and out as required on start up as it did the realignment.  We could use a CompiledMethodTrailer that encoded source in the method, which would avoid any issues with source being compacted, etc.  The methods could be lazily generated.</div><div class="gmail_extra"><br></div><div class="gmail_extra">So the referent class would be auto-generated from a typedef above.  I would also consider writing a simple compiler from typedefs to specs (redefined to support the alignment you want).  While Bert's suggestion of using the tool that outputs xml is a good one. it is yet another external dependency.  I favor running the C compiler with the -P argument (which runs the preprocessor and outputs the preprocessor output) and then writing a C parser that only parses type and function declarations, skipping over C bodies.  the C syntax is quite simple.  Its the preprocessor and pragma extensions etc that complete things.  The fatal flaw in DLLCC was to try and parse arbitrary input files, hence having to handle preprocessing,but C;s preprocessor knows no structure, and hence its enormously difficult to parse pre-preprocessed C.  But pre-processed C is much more manageable.  We could provide tooling to auto generate interfaces derived from preprocessed header files.  But we would not attempt to support macros, leaving it up to the programmer to convert any macros into methods by hand.</div><div class="gmail_extra"><br></div><div class="gmail_extra">As far as importing the values of #defines, the approach I've outlined before which Monty is having a look at, where we generate a program that when run, prints easily parseable definitions, e.g. as STON, is a good one.  Someone working on the FFI can be expected to have a C compiler available, which means we can preprocess and compile programs.  So limiting ourselves to what we can do simply with these two is a good idea.  A full blown C parser is, as DLLCC demonstrates, a practical impossibility.</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>