[Vm-dev] Alien/FFI issue with large struct passed as value and how to load vmmaker?

Eliot Miranda eliot.miranda at gmail.com
Thu Apr 4 19:23:24 UTC 2019


On Thu, Apr 4, 2019 at 11:43 AM Eliot Miranda <eliot.miranda at gmail.com>
wrote:

> Hi Holger,
>
> On Thu, Apr 4, 2019 at 10:04 AM Holger Freyther <holger at freyther.de>
> wrote:
>
>>
>> > On 3. Apr 2019, at 23:50, Eliot Miranda <eliot.miranda at gmail.com>
>> wrote:
>> >
>> > Hi Holger,
>>
>> > It's represented as FFIExternalStructure subclass: #CXCursor. In the
>> case of the callback the handle is an instance of
>> FFIExternalStructureReferenceHandle with an Alien embedded into it.
>> >
>> > What is the C signature of the callback function, and what is the
>> source of the marshaling method in the relevant Callback subclass's
>> signatures protocol?
>> > Also, what's the callout's signature and what is the Smalltalk code for
>> the call?
>>
>>
>> C declaration:
>>
>> typedef enum CXChildVisitResult(* CXCursorVisitor) (CXCursor cursor,
>> CXCursor parent, CXClientData client_data);
>>
>> and passed to the c function below.
>>
>> unsigned clang_visitChildren    (CXCursor parent, CXCursorVisitor
>> visitor,  CXClientData client_data );
>>
>>
>> Smalltalk Source:
>>
>>         acceptCallbackFn :=
>>            FFICallback
>>                 signature:  #( CXChildVisitResult (
>>                                                                 CXCursor
>> cursor,
>>                                                                 CXCursor
>> parent,
>>                                                                 CXString
>> client_data))
>>
>
> somewhere in the Callback hierarchy there should me a marshaling method
> for the platform you're on that matches that signature.  Fo example, in
> Squeak if I'm calling, say, sort, then there's a callback such as
>
> Callback
> signature:  #(int (*)(const void *, const void *))
> block: [ :arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1)) sign].
>
> to marshal the callback's incoming arguments each platform needs a
> suitable marshaling method that the Callback machinery matches to the
> signature.  Here they are from Squeak:
>
> Callback methods for signatures
> voidstarvoidstarRetint: callbackContext regs: regsAlien
> <signature: #(int (*)(const void *, const void *))>
> self subclassResponsibility
>
> CallbackForARM32 methods for signatures
> voidstarvoidstarRetint: callbackContext regs: regsAlien
> <signature: #(int (*)(const void *, const void *))>
> ^callbackContext wordResult:
> (block
> value: (Alien forPointer: (regsAlien unsignedLongAt: 1))
> value: (Alien forPointer: (regsAlien unsignedLongAt: 5)))
>
> CallbackForWin64X64 methods for signatures
> voidstarvoidstarRetint: callbackContext regs: regsAlien
> <signature: #(int (*)(const void *, const void *))>
> ^callbackContext wordResult:
> (block
> value: (Alien forPointer: (regsAlien unsignedLongLongAt: 1))
> value: (Alien forPointer: (regsAlien unsignedLongLongAt: 9)))
>
> CallbackForX64 methods for signatures
> voidstarvoidstarRetint: callbackContext regs: regsAlien
> <signature: #(int (*)(const void *, const void *))>
> ^callbackContext wordResult:
> (block
> value: (Alien forPointer: (regsAlien unsignedLongLongAt: 1))
> value: (Alien forPointer: (regsAlien unsignedLongLongAt: 9)))
>

Missed one (finger trouble)

CallbackForIA32 methods for signatures
voidstarvoidstarRetint: callbackContext sp: spAlien
<signature: #(int (*)(const void *, const void *))>
^callbackContext wordResult:
(block
value: (Alien forPointer: (spAlien unsignedLongAt: 1))
value: (Alien forPointer: (spAlien unsignedLongAt: 5)))


> What are is method for your platform?
>
>
> CXChildVisitResult is an enum, CXCursor/CXString are FFIExternalStructure
>> subclasses.
>>
>>
>>
>> Smalltalk code:
>>
>>
>>         Libclang clang_visitChildren__parentCursor: rootCursor
>>                                    visitorCallback: acceptCallbackFn
>>                                         clientData: rootClientData.
>>
>> >>#clang_visitChildren__parentCursor: parent
>>                   visitorCallback: visitor
>>                        clientData: client_data
>>         ^ self ffiCall: #( uint clang_visitChildren(
>>                                                                 CXCursor
>> parent,
>>
>> CXCursorVisitor visitor,
>>
>> CXClientData client_data))
>>
>>
>>
>> > Or do I chase it from the wrong end?
>> >
>> > Without the code I can't help, hence my questions above.
>>
>> The full code is in Ben's LibclangPractice (
>> http://smalltalkhub.com/#!/~BenComan/LibclangPractice). I have set a
>> breakpoint in LibclangTest>>#visitChildrenCallbackReturning: to look at the
>> cursor variable and call it's methods. I think my  Pharo PR (
>> https://github.com/pharo-project/pharo/pull/3136/files#diff-8f4b31166c3a817dd8ad1f0518ae633a)
>> is fixing the callback handling in Unified-FFI.
>>
>>
>> I think I have stumbled into three separate bugs and I just noticed that
>> they are Pharo specific. Unified-FFI doesn't seem to exist for Squeak.
>>
>>
>> 1st) an Alien ending inside a handle of a FFIExternalStructure
>> sub-instance. I have made a PR for it and I think it is reasonable to turn
>> the Alien into an ExternalAddress early.
>>
>> 2nd) Pushing a FFIExternalStructure sub-instance with a
>> FFIExternalStructureReferenceHandle in it to the stack doesn't work.
>> Squeak+ThreadedFFIPlugin simply don't know what a
>> FFIExternalStructureReferenceHandle valueOOP is.
>>
>>
>> 3rd) Returning a struct from the callback doesn't to work either. That's
>> a UnifiedFFI bug as well:
>>
>> In FFICallbackParameterTests>>#testPassingStructureInTheStack
>>
>>         | param |
>>         callback := FFICallback
>>                 signature: #(int (FFITestStructureSmallIntFloatStructure
>> a))
>>                 block: [ :a |
>>                         self assert: a x equals: 2.0.
>>                         self assert: a y equals: 3. ..
>>
>> change the "int" to "FFITestStructureSmallIntFloatStructure" and the
>> first assertion will fail. The value of "a x" becomes 3. I have not
>> debugged this.
>>
>>
>> I think only 2nd) is relevant to this list. Support for
>> FFIExternalStructureReferenceHandle will add one level of indirection.
>>
>>
>>
>
> --
> _,,,^..^,,,_
> best, Eliot
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20190404/19aa18cb/attachment.html>


More information about the Vm-dev mailing list