<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        
                                        
                                            
                                        
                                        
                                        Let me add that I am really surprised (and a little bit worried) that this little requirement of "wrap alias to atomic into referentClass on return" turned into such a huge proposal of yours.<div><br></div><div>All that other coercing stuff could easily be added via #doesNotCoerce: as proposed here: </div><div><a href="http://forum.world.st/FFI-Plugin-Proposal-Add-doesNotCoerce-for-like-doesNotUnderstand-td5118724.html"><span style="font-size: 10pt">http://forum.world.st/FFI-Plugin-Proposal-Add-doesNotCoerce-for-like-doesNotUnderstand-td5118724.html</span></a><br><div><br></div><div>Please, try to understand the relationship between ExternalData and ExternalStructure/Union/TypeAlias. It's so simple. But maybe not so clear. ExternalData is not an implementation detail. It's part of the public interface; it's like Array but as a composition of handle and type. And maybe size and offset -- but that's due to heap memory management part.</div><div><br></div><div>Type safety is valuable, of course. Maybe you can give more examples of what you want to achieve. :-)</div><div><br></div><div>Best,</div><div>Marcel</div></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 22.06.2020 10:31:47 schrieb Marcel Taeumel <marcel.taeumel@hpi.de>:</p><div style="font-family:Arial,Helvetica,sans-serif"><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        > <span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">throw that code away, and have a look at  in VMMakerInbox, you will understand better...</span><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Not so sure ... because I think we do not agree on the status quo yet. We should do that first. Understand the compiledSpec as is. Then move forward.</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">> </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">So hopefully, we shall throw away the FFIFlagStructure and make your life easier at image side :)</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Not so sure. See above. </span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px">Best,</span></span></div><div><span style="font-family: Arial, Helvetica, sans-serif"><span style="font-size: 13px">Marcel</span></span></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 22.06.2020 10:28:12 schrieb Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:</p><div style="font-family:Arial,Helvetica,sans-serif">
<div dir="ltr"><div>No, no,</div><div>throw that code away, and have a look at  in VMMakerInbox, you will understand better...</div><div><br></div><div>In fact, if you read my proposals, I'd like to get rid of FFIFlagStructure altogether...</div><div>Either a type is atomic or composite, it's not both nor neither...</div><div>So we ain't gonna need 2 flags FFIFlagAtomic and FFIFlagStructure.</div><div><br></div><div>So hopefully, we shall throw away the FFIFlagStructure and make your life easier at image side :)<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 22 juin 2020 à 10:19, Marcel Taeumel <<a href="mailto:marcel.taeumel@hpi.de">marcel.taeumel@hpi.de</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex;border-left: 1px solid rgb(204,204,204);padding-left: 1ex;min-width: 500px"><div id="gmail-m_3491715305796571077__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: rgb(0,0,0)">
                                        
                                        
                                            
                                        
                                        
                                        Hi Nicolas,<div><br></div><div>sure, there might be a difference. But you have all the information you need directly in the plugin already:</div><div><br></div><div><img id="gmail-m_3491715305796571077bb19c456-0c4e-450b-a8d3-2479268b49e5" src="cid:172db1f07c2cb971f161" width="auto"></img><br></div><div><br></div><div>Let me catch up on this later this week.</div><div><br></div><div>Best,</div><div>Marcel</div><div></div>
                                        
                                        <blockquote 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:rgb(170,170,170);margin-top:10px">Am 22.06.2020 09:56:05 schrieb Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>>:</p><div style="font-family:Arial,Helvetica,sans-serif">
<div dir="ltr"><div>Hi Marcel,</div><div>So you mean that I don't really need to distinguish pointer to struct and pointer to atomic type alias?</div><div>Maybe...</div><div><br></div><div>There is currently a difference:</div><div>- an atomic type alias has an immediate value as handle</div><div>  it thus cannot be passed as parameter by reference</div><div>  (well, for aliases to pointers, I don't really know...)<br></div><div>- a struct has a memory zone as value (ExternalAddress or direct ByteArray)</div><div> it thus can be passed as parameter by reference without having to resort to an ExternalData.</div><div>See ffiPassStructureArgumentByReference: oop Class: oopClass expectedClass: argClass In: calloutState</div><div>vs ffiPassAtomicArgumentByReference: oop Class: oopClass expectedClass: argClass In: calloutState</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 22 juin 2020 à 09:18, Marcel Taeumel <<a href="mailto:marcel.taeumel@hpi.de" target="_blank">marcel.taeumel@hpi.de</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex;border-left: 1px solid rgb(204,204,204);padding-left: 1ex;min-width: 500px"><div id="gmail-m_3491715305796571077gmail-m_5745492037820762996__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: rgb(0,0,0)">
                                        
                                        
                                            
                                        
                                        
                                        Hi Nicolas,<div></div>
                                        
                                        <div><br></div><div>thanks! :-) <span style="font-size: 10pt">I will take a look at it during this week, I hope. </span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">Here is a first thought:</span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">I don't think that the pointer types for external structs should have the FFIFlagStructure."referentClass" should be more than enough for the FFI plugin side for both coercing and return-value packaging.</span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">So, -1 for now but maybe I overlooked a use case. Raising this FFIFlagStructure here for such pointer types really messes up a lot of my current conceptual model about the relationship of ExternalStructure and ExternalType/ExternalStructureType. :-)</span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">Why is "referentClass" not enough for the plugin side? Just check for ifNil, if not, instantiate and put instVar 0 to the return value. Done. ;-) For coercing, just compare argument class with "referentClass" in the argType; then check for the pointer flag. Maybe discriminate between ByteArray and ExternalAddress. </span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">...please don't raise FFIFlagStructure for pointer types for external structures... pretty please ^__^</span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">Best,</span></div><div><span style="font-size: 10pt">Marcel</span></div><div><span style="font-size: 10pt"><br></span></div><blockquote 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:rgb(170,170,170);margin-top:10px">Am 21.06.2020 22:34:09 schrieb <a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a> <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>>:</p><div style="font-family:Arial,Helvetica,sans-serif">Nicolas Cellier uploaded a new version of FFI-Kernel to project FFI Inbox:<br><a href="http://source.squeak.org/FFIinbox/FFI-Kernel-nice.119.mcz" target="_blank">http://source.squeak.org/FFIinbox/FFI-Kernel-nice.119.mcz</a><br><br>==================== Summary ====================<br><br>Name: FFI-Kernel-nice.119<br>Author: nice<br>Time: 21 June 2020, 10:34:00.334284 pm<br>UUID: 3f2eca9d-8f55-476c-a0b0-c5ed6368a6b4<br>Ancestors: FFI-Kernel-nice.118<br><br>Make the compiledSpecs of struct pointers conform to the experimental FFI branch (thru #adjustPointerType)<br><br>See <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/tree/experimental_FFI" target="_blank">https://github.com/OpenSmalltalk/opensmalltalk-vm/tree/experimental_FFI</a><br><br>Simplify a bit ExternalData access (at: / at:put:).<br>The assumption that ExternalDataType is the type of the contents and not the type of the reference helps simplifying IMO.<br><br>We might want to make it more complete once we deal with pointer arity.<br>It's not the case yet.<br><br>=============== Diff against FFI-Kernel-nice.118 ===============<br><br>Item was changed:<br>  ----- Method: ExternalData>>at: (in category 'accessing') -----<br>  at: index<br>  <br>-        self<br>-                 assert: [index = 1 or: [type isAtomic]]<br>-              description: 'Should not read non-atomic pointer as array'.<br>- <br>       ((1 > index) or: [size notNil and: [index > size]])<br>             ifTrue: [^ self errorSubscriptBounds: index].<br>  <br>+    ^ type<br>-       ^ type asNonPointerType<br>               handle: handle<br>+               at: ((index-1) * type byteSize) + 1!<br>-                 at: ((index-1) * type asNonPointerType byteSize) + 1!<br><br>Item was changed:<br>  ----- Method: ExternalData>>at:put: (in category 'accessing') -----<br>  at: index put: value<br>  <br>-  self<br>-                 assert: [index = 1 or: [type isAtomic]]<br>-              description: 'Should not read non-atomic pointer as array'.<br>- <br>       ((1 > index) or: [size notNil and: [index > size]])<br>             ifTrue: [^ self errorSubscriptBounds: index].<br>  <br>+    ^ type<br>-       ^ type asNonPointerType<br>               handle: handle<br>+               at: ((index-1) * type byteSize) + 1<br>-          at: ((index-1) * type asNonPointerType byteSize) + 1<br>                  put: value!<br><br>Item was changed:<br>  ----- Method: ExternalStructure class>>compileAllFields (in category 'system startup') -----<br>  compileAllFields<br>    "<br>        ExternalStructure compileAllFields<br>    "<br>+       | priorAuthorInitials |<br>-      | priorAuthorInitials fieldSpec |<br>     priorAuthorInitials := Utilities authorInitialsPerSe.<br>         [Utilities setAuthorInitials: 'FFI'.<br>          <br>              self allStructuresInCompilationOrder do: [:structClass |<br>+                     | fieldSpec |<br>                         fieldSpec := structClass fields.<br>                      self flag: #discuss. "mt: Why do we need that extra layout check? Performance gain is minimal..."<br>                   (structClass hasFieldLayoutChanged: fieldSpec)<br>                                ifTrue: [structClass compileFieldsSilently: fieldSpec].<br>                       structClass externalType "asNonPointerType"<br>                                 compiledSpec: structClass compiledSpec;<br>+                              byteAlignment: structClass byteAlignment;<br>+                            adjustPointerType.<br>-                           byteAlignment: structClass byteAlignment.<br>                     structClass organization removeEmptyCategories].<br>              "Compilation of fields only needs external types temporarily. Non-weak references to external types are only in methods with FFI calls."<br>            ExternalType cleanupUnusedTypes.<br>  <br>          ] ensure: [Utilities setAuthorInitials: priorAuthorInitials]!<br><br>Item was added:<br>+ ----- Method: ExternalStructureType>>adjustPointerType (in category 'private') -----<br>+ adjustPointerType<br>+  self isPointerType<br>+           ifFalse: [self asPointerType<br>+                                 compiledSpec: (WordArray with: ((self compiledSpec first<br>+                                             bitAnd: FFIFlagAtomic + FFIFlagStructure)<br>+                                            bitOr: self class pointerSpec));<br>+                              byteAlignment: self class pointerAlignment]!<br><br>Item was changed:<br>  ----- Method: ExternalType class>>initializeStructureTypes (in category 'class initialization') -----<br>  initializeStructureTypes<br>         "Reset all non-pointer struct types to zero and their pointer companions to the appropriate pointer size."<br>  <br>      StructTypes ifNil: [<br>                  StructTypes := WeakValueDictionary new].<br>      <br>      self cleanupUnusedTypes.<br>      <br>      StructTypes valuesDo:[:structType |<br>           structType "asNonPointerType"<br>                       compiledSpec: (WordArray with: self structureSpec);<br>                   byteAlignment: nil.<br>           structType asPointerType<br>+                     compiledSpec: (WordArray with: self pointerSpec + self structureSpec);<br>-                       compiledSpec: (WordArray with: self pointerSpec);<br>                     byteAlignment: nil].!<br><br>Item was changed:<br>  ----- Method: ExternalType>>handle:at: (in category 'external data') -----<br>  handle: handle at: byteOffset<br>       "Read the receiver's external type using the given handle and the byteOffset. This is the dynamic version of #readFieldAt:."<br>        <br>+     | address value |<br>-    | result |<br>-   self checkType.<br>-      <br>      self isPointerType<br>+           ifTrue:<br>+                      [address := handle pointerAt: byteOffset length: self byteSize.<br>+                      ^ExternalData<br>+                                fromHandle: address<br>+                          type: self asNonPointerType].<br>+        self isAtomic<br>+                ifTrue:<br>+                      ["Answer atomic value"<br>+                     value := handle<br>-              ifFalse: [<br>-                   "Answer atomic value"<br>-                      ^ handle<br>                              perform: (AtomicSelectors at: self atomicType)<br>+                               with: byteOffset.<br>+                    ^referentClass ifNil: [value] ifNotNil: [referentClass fromHandle: value]].<br>+ <br>+      referentClass isNil<br>+          ifTrue: [self error: 'unknown type'].<br>+        self isEmpty ifTrue: [self error: 'Empty structure'].<br>+                <br>+     ^referentClass fromHandle: (handle structAt: byteOffset length: self byteSize)!<br>-                              with: byteOffset]<br>-            ifTrue: [<br>-                    ^ referentClass<br>-                              ifNotNil: [<br>-                                  "Answer structure, union, or type alias"<br>-                                   referentClass fromHandle: (handle pointerAt: byteOffset length: self byteSize)]<br>-                              ifNil: [<br>-                                     "Answer wrapper that points to external data"<br>-                                      result := ExternalData<br>-                                               fromHandle: (handle pointerAt: byteOffset length: self byteSize)<br>-                                             type: self.<br>-                                  self = ExternalType string<br>-                                           ifTrue: [result fromCString]<br>-                                                 ifFalse: [result]]]!<br><br>Item was changed:<br>  ----- Method: ExternalType>>handle:at:put: (in category 'external data') -----<br>  handle: handle at: byteOffset put: value<br>         "Write a value using the receiver's external type at the given handle and byteOffset. This is the dynamic version of #writeFieldAt:with:."<br>  <br>-     self checkType.<br>-      <br>      self isPointerType<br>-           ifFalse: [ "set atomic value"<br>-                      self flag: #addTypeCheck. "mt: Note that there is currently no mapping from objects that represent valid atomics to atomic types."<br>-                         handle<br>-                               perform: ((AtomicSelectors at: self atomicType), 'put:') asSymbol<br>-                            with: byteOffset<br>-                             with: value]<br>                  ifTrue: [ "set pointer to struct/union/alias"<br>+                      self assert: [value externalType == self asNonPointerType].<br>-                  self assert: [value externalType == self].<br>                    handle<br>                                pointerAt: byteOffset<br>                                 put: value getHandle<br>+                                 length: self byteSize.<br>+                       ^value].<br>+             <br>+     self isAtomic<br>+                ifTrue:<br>+                      [ "set atomic value"<br>+                       self flag: #addTypeCheck. "mt: Note that there is currently no mapping from objects that represent valid atomics to atomic types."<br>+                         handle<br>+                               perform: ((AtomicSelectors at: self atomicType), 'put:') asSymbol<br>+                            with: byteOffset<br>+                             with: value.<br>+                         ^value].<br>+                     <br>+     referentClass isNil<br>+          ifTrue: [self error: 'unknown type'].<br>+        self isEmpty ifTrue: [self error: 'Empty structure'].<br>+ <br>+    self assert: [value externalType == self].<br>+   handle structAt: byteOffset put: value getHandle length: self byteSize.<br>+      ^value<br>+       !<br>-                            length: self byteSize].!<br><br><br></div></blockquote></div><br>
</blockquote></div>
</div></blockquote></div><br>
</blockquote></div>
</div></blockquote>
                                        </div></div></blockquote></div>