<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        I think I withdraw this proposal. C stuff would be better off in a class that could safely be unloaded after all external shared pools are installed. To save resources on the target platform if required.<div><br></div><div>Best,</div><div>Marcel</div><div class="mb_sig"></div>
                                        <blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 29.05.2020 16:18:52 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif">A new version of FFI-Kernel was added to project FFI Inbox:<br>http://source.squeak.org/FFIinbox/FFI-Kernel-mt.78.mcz<br><br>==================== Summary ====================<br><br>Name: FFI-Kernel-mt.78<br>Author: mt<br>Time: 29 May 2020, 4:18:42.331595 pm<br>UUID: 1d41e42b-d401-5e41-8bb8-bec2813972e0<br>Ancestors: FFI-Kernel-mt.77<br><br>Proposal to store type information for C code generation in FFI's atomic types.<br><br>An alternative would be to add two new tables as class variables -- just like AtomicTypeNames -- to not increase the size of ExternalType instances. I am not familiar with the implementation of the FFI plugin in the osvm. So this is just a guess. :-)<br><br>(Also see my question about byte alignment here: http://forum.world.st/FFI-Byte-alignment-tp5117408.html --- I discarded the dead code path in this proposal already.)<br><br>=============== Diff against FFI-Kernel-mt.77 ===============<br><br>Item was changed:<br>  Object subclass: #ExternalType<br>+       instanceVariableNames: 'compiledSpec referentClass referencedType pointerSize byteAlignment cTypeName cFormatPlaceholder'<br>-    instanceVariableNames: 'compiledSpec referentClass referencedType pointerSize byteAlignment'<br>          classVariableNames: 'AtomicSelectors AtomicTypeNames AtomicTypes StructTypes'<br>         poolDictionaries: 'FFIConstants'<br>      category: 'FFI-Kernel'!<br>  <br>  !ExternalType commentStamp: 'eem 6/25/2019 10:39' prior: 0!<br>  An external type represents the type of external objects.<br>  <br>  Instance variables:<br>    compiledSpec    <wordarray>               Compiled specification of the external type<br>   referentClass   <behavior |="" nil="">        Class type of argument required<br>       referencedType  <externaltype>    Associated (non)pointer type with the receiver<br>        pointerSize             <integer |="" nil="">         The size of a pointer if the external type is a pointer or is a structure containing a pointer.<br>       byteAlignment   <integer |="" nil="">         The desired alignment for a field of the external type within a structure.  If nil it has yet to be computed.<br>  <br>  Compiled Spec:<br>  The compiled spec defines the type in terms which are understood by the VM. Each word is defined as:<br>   bits 0...15     - byte size of the entity<br>     bit 16          - structure flag (FFIFlagStructure)<br>                             This flag is set if the following words define a structure<br>          bit 17          - pointer flag (FFIFlagPointer)<br>                                 This flag is set if the entity represents a pointer to another object<br>       bit 18          - atomic flag (FFIFlagAtomic)<br>                                   This flag is set if the entity represents an atomic type.<br>                             If the flag is set the atomic type bits are valid.<br>          bits 19...23    - unused<br>      bits 24...27    - atomic type (FFITypeVoid ... FFITypeDoubleFloat)<br>    bits 28...31    - unused<br>  <br>  Note that all combinations of the flags FFIFlagPointer, FFIFlagAtomic, and FFIFlagStructure are invalid, EXCEPT from the following:<br>  <br>       FFIFlagPointer + FFIFlagAtomic:<br>               This defines a pointer to an atomic type (e.g., 'char*', 'int*').<br>             The actual atomic type is represented in the atomic type bits.<br>  <br>    FFIFlagPointer + FFIFlagStructure:<br>            This defines a structure which is a typedef of a pointer type as in<br>                   typedef void* VoidPointer;<br>                    typedef Pixmap* PixmapPtr;<br>            It requires a byte size of four or eight (e.g. a 32-bit or 64-bit pointer) to work correctly.<br>  <br>  [Note: Other combinations may be allowed in the future]<br>  !<br><br>Item was changed:<br>  ----- Method: ExternalType class>>initializeAtomicTypes (in category 'class initialization') -----<br>  initializeAtomicTypes<br>+  "For a discussion about long vs. int see http://forum.world.st/Re-squeak-dev-64-bit-FFI-was-porting-Croquet-to-Squeak6-0-alpha-tp5113318.html."<br>+    <br>      "ExternalType initialize"<br>+  | atomicType byteSize type typeName byteAlignment cTypeName cFormatPlaceholder |<br>-     | atomicType byteSize type typeName byteAlignment |<br>   #(<br>+           "name              atomic id               byte size       byte alignment  C type name                     C printf % format"<br>+              ('void'                 0                               0                       0                               'void'                                  'p')<br>+                 ('bool'                 1                               1                       1                               'int'                                           'd')<br>+                 ('byte'                 2                               1                       1                               'unsigned char'                 'hhu') "Not 'c' to avoid conversion issues"<br>+                ('sbyte'        3                               1                       1                               'signed char'                   'hhd') "Not 'c' to avoid conversion issues"<br>+                ('ushort'       4                               2                       2                               'unsigned short'                'hu')<br>+                ('short'                5                               2                       2                               'signed short'                  'hd')<br>+ "!!!!!!"     ('ulong'        6                               4 "!!!!!!"            4                               'unsigned int'                  'u') "Not 'lu' bc. not unsigned long, see above"<br>+ "!!!!!!"        ('long'                 7                               4 "!!!!!!"            4                               'signed int'                            'd') "Not 'ld' bc. not signed long, see above"<br>+             ('ulonglong' 8                          8                       8                               'unsigned long long'    'llu')<br>+               ('longlong'     9                               8                       8                               'signed long long'              'lld')<br>+               ('char'                 10                              1                       1                               'unsigned char'                 'hhu') "Not 'c' to avoid conversion issues"<br>+                ('schar'        11                              1                       1                               'signed char'                   'hhd') "Not 'c' to avoid conversion issues"<br>+                ('float'                12                              4                       4                               'float'                                 'g') "Not 'G' bc. notation in lowercase letters"<br>+           ('double'       13                              8                       8                               'double'                                        'g') "Not 'G' bc. notation in lowercase letters"<br>+ "TODO: ('longdouble' 14                      10                      16? 4?                  'long double'                   'Lg')"<br>-          "name              atomic id               byte size       byte alignment"<br>-                 ('void'                 0                               0                       0)<br>-           ('bool'                 1                               1                       1)<br>-           ('byte'                 2                               1                       1)<br>-           ('sbyte'        3                               1                       1)<br>-           ('ushort'       4                               2                       2)<br>-           ('short'                5                               2                       2)<br>-           ('ulong'        6                               4                       4)<br>-           ('long'                 7                               4                       4)<br>-           ('ulonglong' 8                          8                       8)<br>-           ('longlong'     9                               8                       8)<br>-           ('char'                 10                              1                       1)<br>-           ('schar'        11                              1                       1)<br>-           ('float'                12                              4                       4)<br>-           ('double'       13                              8                       8)<br>    ) do:[:typeSpec| | compiled |<br>                 typeName := typeSpec first.<br>           atomicType := typeSpec second.<br>                byteSize := typeSpec third.<br>           byteAlignment := typeSpec fourth.<br>+            cTypeName := typeSpec fifth.<br>+                 cFormatPlaceholder := typeSpec sixth.<br>+                <br>+             "1) Regular type form"<br>-             "On 32 bits Windows and MacOS, double and long have an alignment of 8. But on Linux, their alignment is 4"<br>-                 (FFIPlatformDescription current wordSize = 4 and: [FFIPlatformDescription current isUnix]) ifTrue: [<br>-                         (#('double longlong ulonglong') includes: typeName) ifTrue: [<br>-                                byteAlignment := 4<br>-                   ]<br>-            ].<br>            compiled := WordArray with: ((byteSize bitOr: FFIFlagAtomic) bitOr:<br>                           (atomicType bitShift: FFIAtomicTypeShift)).<br>           type := (AtomicTypes at: typeName).<br>+          type<br>+                         compiledSpec: compiled;<br>+                      byteAlignment: byteAlignment;<br>+                        cTypeName: cTypeName;<br>+                        cFormatPlaceholder: '%', cFormatPlaceholder.<br>+                 <br>+             "2) Pointer type form"<br>-             type compiledSpec: compiled;<br>-                         byteAlignment: byteAlignment.<br>                 compiled := WordArray with: ((self pointerSpec bitOr: FFIFlagAtomic) bitOr:<br>                           (atomicType bitShift: FFIAtomicTypeShift)).<br>           type asPointerType<br>                    byteAlignment: self pointerAlignment;<br>+                        compiledSpec: compiled;<br>+                      cTypeName: cTypeName, ' *';<br>+                  cFormatPlaceholder: '%p'.<br>+ <br>-                        compiledSpec: compiled.<br>       ].!<br><br>Item was added:<br>+ ----- Method: ExternalType>>cFormatPlaceholder (in category 'accessing') -----<br>+ cFormatPlaceholder<br>+ <br>+     ^ cFormatPlaceholder!<br><br>Item was added:<br>+ ----- Method: ExternalType>>cFormatPlaceholder: (in category 'accessing') -----<br>+ cFormatPlaceholder: aString<br>+ <br>+         cFormatPlaceholder := aString.!<br><br>Item was added:<br>+ ----- Method: ExternalType>>cTypeName (in category 'accessing') -----<br>+ cTypeName<br>+ <br>+   ^ cTypeName!<br><br>Item was added:<br>+ ----- Method: ExternalType>>cTypeName: (in category 'accessing') -----<br>+ cTypeName: aString<br>+ <br>+    cTypeName := aString.!<br><br><br></integer></integer></externaltype></behavior></wordarray></div></blockquote></div>