From: SourceForge.net <no...@so...> - 2005-08-08 12:30:49
|
Bugs item #1211847, was opened at 2005-05-31 10:37 Message generated for change (Comment added) 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: Open 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: 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 |