|
From: SourceForge.net <no...@so...> - 2006-01-31 13:31:12
|
Bugs item #1211847, was opened at 2005-05-31 10:37 Message generated for change (Settings changed) made by hoehle You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101355&aid=1211847&group_id=1355 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: ffi Group: lisp error >Status: Closed Resolution: None Priority: 5 Submitted By: Jörg Höhle (hoehle) Assigned to: Jörg Höhle (hoehle) Summary: ffi refuses c-struct conversion Initial Comment: Here's something I'd like to submit to your analysis before doing any changes. Compilation of cl-sdl revealed the following bug in clisp: src/foreign.d says abount equal_fvd(): "According to the ANSI C rules, two "c-struct"s are only equivalent if they come from the same declaration. Same for "c-union"s." As a result, equal_fvd() is implemented in terms of EQ rather than EQUALP when comparing the internal representation of c-struct or c-union. However, upon file-compilation of def-call-out, the value of parse-c-function (i.e. the nested #(c-struct ...) array) gets integrated into the .fas, which looses object identity. With ffi forms across 2 compiled files, we obtain 2 different arrays even though the source code refers to a single c-struct type definition (i.e. (def-c-type event (c-union ...))). As a result, completely valid code like File A: (def-c-type event (c-union ...)) (def-call-out poll-event (:arguments (c-pointer event))) File B: (with-foreign-object (e 'event (poll-event))) fails with a conversion error raised by equal_fvd(). #<FOREIGN-VARIABLE "EXEC-ON-STACK" #xBFFF8CAC> kann nicht in den Foreign-Typ #(C-STRUCT FOO NIL #(I D) #<COMPILED-FUNCTION :LAMBDA> UINT8 DOUBLE-FLOAT) umgewandelt werden. Work-around: do not load .fas file, use either .lisp or (load :compiling t) There are two solution paths I'd like to discuss: A) Change def-call-out so as to not inline (expand into) the result of parse-c-function and rather call parse-c-type at load-time. B) Implement equal_fvd() like EQUALP for union and structs. C) Do both :-) Note that A) may still lead to conversion errors when redefining an already existing type while some other code still refers to the original vector. Similar to re-eval'ing defclass, although much harder to understand from a user POV (s/he sees to identical-looking type declarations as reported by deparse-c-type and fails to understand why there's a conversion error). Note that B) causes additional run-time overhead for each function call, which could be avoided if EQ-identity were preserved (via A or C). Whereas A) would just make loading slower -- presumably invoking parse-c-function at load-time is slower than reading a #() array, and needs some more thought upon whether delegating that to load-time causes other side-effects. BTW, note that the AFFI def-lib-call-out macro expands to a literal parse-c-function instead of its value -- it is not subject to this bug. Actually, thinking again about the matter, there's not even a need for 2 files. (def-c-struct foo (i uint8) (d double-float)) (def-call-out fvd3 (:name "ffi_identity") (:arguments (x (c-pointer foo))) (:return-type (c-pointer foo))) (defun fvd03 (n) (with-foreign-object (x 'foo) (fvd3 x))) Loading this from a .fas is enough to trigger the bug. Regards, Jörg Höhle. ---------------------------------------------------------------------- Comment By: Jörg Höhle (hoehle) Date: 2006-01-31 14:31 Message: Logged In: YES user_id=377168 thank you for your bug report. the bug has been fixed in the CVS tree. you can either wait for the next release (recommended) or check out the current CVS tree (see http://clisp.cons.org) and build CLISP from the sources (be advised that between releases the CVS tree is very unstable and may not even build on your platform). ---------------------------------------------------------------------- Comment By: Jörg Höhle (hoehle) Date: 2005-08-08 14:30 Message: Logged In: YES user_id=377168 Sorry, my patch is not ready yet. I realized late that some PARSE-C-FUNCTION might be unavoidable at some early time, since the compiler wants to know the function's signature. Initially, I wanted to fix several problems at once: do not perform side-effects during macroexpansion (such as setting the default foreign language), reduce number of calls to parse-c-function etc. Now that'll have to wait until at east after my vacation. ---------------------------------------------------------------------- Comment By: Jörg Höhle (hoehle) Date: 2005-06-01 15:17 Message: Logged In: YES user_id=377168 Now that same issue hit me trying to use cl-gd. I just realized that a recursive EQUALP cannot work, since it may lead to infinite recursion for some structures (those with :pointer-self, e.g. linked list style structure etc.). ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101355&aid=1211847&group_id=1355 |