Hi Ben,

On Tue, Sep 27, 2016 at 8:40 AM, Ben Coman <b...@openinworld.com> wrote:

> First, my C is a bit rusty so a question about semantics...
>
>   int * a;
>   typedef int * MyInt;
>   MyInt b;
>
> So obviously the type of 'a' is a pointer,
> but is the type of 'b' a pointer?
> My intuition is that its not, since the pointer is wrapped inside the type.
>

Yes it is.  MyInt (a bad name) is a type that is a pointer to an int.  So
something of type MyInt is of type pointer to int.


> Now in my UFFI tutorial
> http://blog.openinworld.com/2016/09/pharo-libclang-ffi-
> part-4-ast-walking-with-visitors-callbacks/
> I have a callback that I've modified here adding the #inspect...
>
>     acceptCallbackFn :=
>      FFICallback
>         signature:  #( CXChildVisitResult (
>                                      CXCursor cursor,
>                                      CXCursor parent,
>                                      CXClientData client_data))
>         block: [ :cursor :parent :clientData |
>             client_data inspect.
>            visitResult add: cursor kind item.
>             aCXChildVisitResult value "@1" ].
>
> This can be invoked by running #testVisitChildrenCallbackBreak
> and an inspector opens on an ExternalAddress instead of
> the expected CXClientData.
>
>     FFIExternalObject subclass: #CXClientData
>         instanceVariableNames: ''
>         classVariableNames: ''
>         package: 'Libclang'
>
> where the FFIExternalObject says...
> "A typical usage of me is to create a subclass, and then use that
> subclass name directly in function signatures ... By putting
> FFIExternalObject subclass ... as a return type into the function
> signature, we are telling the code generator to ***automatically***
> convert the return value into an instance of a given class and
> initialize its handle to the value returned by the function."
>
>
> This decision to return ExternalAddress instead of CXClientData
> occurs here...
>   FFIExternalObjectType(FFIExternalType)>>handle: aHandle at: index
>        self isPointer ifTrue: [ ^ aHandle pointerAt: index ].
>        ^ self basicHandle: aHandle at: index
>
> since...
>   FFIExternalType>>isPointer
>       ^ self pointerArity > 0
>
> and...
>   FFIExternalObjectType(FFIExternalReferenceType)>>naturalPointerArity
>       ^ 1
>
> So this naturalPointerArity=1 represents the situation presented with
> the C code at the top.  So should #isPointer consider only the
> absolute pointerArity, or should is be...
>
>   FFIExternalType>>isPointer
>       ^ self pointerArity > self class naturalPointerArity
>
> Indeed, if I do that, plus these two additions copied from
> FFIExternalStructure...
>
>   FFIExternalReferenceType>>basicHandle: aHandle at: index
>       ^ self objectClass fromHandle: aHandle.
>
>   FFIExternalReference>>fromHandle: aHandle
>       ^self basicNew setHandle: aHandle
>
> Now running #testVisitChildrenCallbackBreak
> opens an inspector opens on a CXClientData as expected.
> And all UFFI tests continue to run fine.
>
>
> One thing I found strange though was...
>   FFIExternalStructureType>>naturalPointerArity
>       ^ 1
>
> I would have thought a struct's natural pointer arity was 0 ?
>
> wdyt?
> cheers -ben
>

This makes my brain hurt.  A pointer is a pointer, whether it points to a
pointer or a datum.  Hence I find the "self pointerArity > self class
naturalPointerArity" approach confusing.

_,,,^..^,,,_
best, Eliot

Reply via email to