[Vm-dev] Alien/FFI issue with large struct passed as value and how to load vmmaker?
Holger Freyther
holger at freyther.de
Thu Apr 4 17:04:05 UTC 2019
> 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))
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.
More information about the Vm-dev
mailing list