[cffi-devel] Next release of CFFI with cffi-libffi

Max Mikhanosha max at openchat.com
Mon Apr 30 22:02:05 UTC 2012


This fixes it for me

(defmethod foreign-type-size ((type symbol))
  (let ((*parse-bare-structs-as-pointers* nil))
    (foreign-type-size (parse-type type))))

The key code path is is this in define-compiler-macro mem-aref

(mem-ref ,ptr ,type (* ,index ,(foreign-type-size (eval type))))

When TYPE is 'FOO, the (foreign-type-size T) method is used, which
uses PARSE-TYPE, which returns (:pointer (:struct foo)), which in in case of 'foo is incorrect
as 'FOO is a structure of size 6, and not a pointer.



At Mon, 30 Apr 2012 23:29:13 +0200,
Stelian Ionescu wrote:
> 
> On Tue, 2012-05-01 at 00:00 +0400, Stas Boukarev wrote:
> > Stas Boukarev <stassats at gmail.com> writes:
> > 
> > > Stelian Ionescu <sionescu at cddr.org> writes:
> > >
> > >> On Thu, 2012-04-19 at 14:46 +0000, Stas Boukarev wrote:
> > >>> Luís Oliveira <luismbo <at> gmail.com> writes:
> > >>> 
> > >>> > 
> > >>> > On Thu, Apr 19, 2012 at 2:50 PM, Stelian Ionescu <sionescu <at> cddr.org> 
> > >>> wrote:
> > >>> > > (with-foreign-object (p '(:struct timespec) 2)
> > >>> > >  (mem-aref p '(:struct timespec) 1))
> > >>> > >
> > >>> > > In order not to break existing code [...]
> > >>> > 
> > >>> > Existing code will not have this (:struct foo) syntax because it was
> > >>> > introduced by the libffi merge. (mem-aref p 'timespec 1) should
> > >>> > exhibit backwards-compatible behaviour.
> > >>> Turns out, the problem is not with mem-aref, but with the mem-aref compile-
> > >>> macro. It binds *parse-bare-structs-as-pointers* to T, whereas mem-aref function 
> > >>> doesn't, this affects the result of foreign-type-size.
> > >>
> > >> Actually it's mem-aref that should bind *parse-bare-structs-as-pointers*
> > >> to T, so I pushed the fix
> > >
> > > This breaks it.
> > And the same problem with *parse-bare-structs-as-pointers* being
> > different is also present in the setf macro for mem-aref.
> 
> Ok, I reverted that patch because it's now obvious that I misunderstood
> the problem, the bug seems to be in the compiler-macro:
> 
> CFFI> (cffi:defcstruct foo
>         (a :uint8))
> => (:STRUCT FOO)
> CFFI> (cffi:with-foreign-object (var 'foo 2)
>         (declare (inline mem-aref))
>         (- (cffi-sys:pointer-address (cffi:mem-aref var 'foo 1))
>            (cffi-sys:pointer-address (cffi:mem-aref var 'foo 0))))
> => 8
> CFFI> (cffi:with-foreign-object (var 'foo 2)
>         (declare (notinline mem-aref))
>         (- (cffi-sys:pointer-address (cffi:mem-aref var 'foo 1))
>            (cffi-sys:pointer-address (cffi:mem-aref var 'foo 0))))
> => 1
> 
> -- 
> Stelian Ionescu a.k.a. fe[nl]ix
> Quidquid latine dictum sit, altum videtur.
> http://common-lisp.net/project/iolib
> 




More information about the cffi-devel mailing list