UFFI #isPointer - absolute or versus naturalPointerArity

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

UFFI #isPointer - absolute or versus naturalPointerArity

Ben Coman
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.


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

Reply | Threaded
Open this post in threaded view
|

Re: UFFI #isPointer - absolute or versus naturalPointerArity

Eliot Miranda-2
Hi Ben,

On Tue, Sep 27, 2016 at 8:40 AM, Ben Coman <[hidden email]> 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