Hi!
Attached is a hasty patch to enable CFFI-SYS:%FOREIGN-FUNCALL and CFFI-SYS:%FOREIGN-FUNCALL-POINTER for LispWorks. The idea is to create one foreign funcallable per signature and cache those in a hash table. I took a quick glance at the source code of CMUCL's ALIEN-FUNCALL and my impression (not really understanding the details) was that CMUCL actually does something similar internally - it creates a "stub" if necessary, depending on the types. As you can observe at the REPL it compiles /something/ when ALIEN-FUNCALL is called.
Granted, it is kind of ugly to call FLI:DEFINE-FOREIGN-FUNCALLABLE in non-top-level position but I think this solution is better than nothing. It looks to me as if FOREIGN-FUNCALL is mostly intended for interactive use and for "one-shot" invocations - correct me if I'm wrong.
I don't know if CMUCL's "stubs" will ever be garbage-collected, the foreign funcallables in my patch certainly won't. I don't expect this to be a big problem, though.
I tried the CFFI test suite and it basically ran through with three exceptions - FUNCALL.FLOAT, DEREF.FLOAT.2, and DEREF.FLOAT.3. My guess is that these are due to LispWorks identifying FLOAT and DOUBLE-FLOAT and are not related to my patch.
Two minor quibbles, unrelated:
1. The documentation says it is only about the cffi-luis branch but it seems to me that the main branch and cffi-luis are almost identical - or did I miss something?
2. This form
(define-foreign-library libcurl (:unix (:or "libcurl.so.3" "libcurl.so")) (t (:default "libcurl")))
in the (very nice, BTW) tutorial didn't work for me on Linux, neither with LispWorks nor with CMUCL. I had to remove the second (:UNIX) line to make it work.
edi@vmware:~$ ls -l /usr/lib/libcurl* lrwxrwxrwx 1 root root 16 Dec 28 19:29 /usr/lib/libcurl.so.3 -> libcurl.so.3.0.0 -rw-r--r-- 1 root root 196632 Dec 7 12:39 /usr/lib/libcurl.so.3.0.0
Cheers, Edi.
On Sun, 2006-01-15 at 00:18 +0100, Edi Weitz wrote:
- The documentation says it is only about the cffi-luis branch but it seems to me that the main branch and cffi-luis are almost identical
- or did I miss something?
It's defunct, and removed in a doc patch coming soon.
This form
(define-foreign-library libcurl (:unix (:or "libcurl.so.3" "libcurl.so")) (t (:default "libcurl")))
in the (very nice, BTW) tutorial didn't work for me on Linux, neither with LispWorks nor with CMUCL. I had to remove the second (:UNIX) line to make it work.
The problem is that try-foreign-library-alternatives depends on the return value of load-foreign-library, which is unspecified. I believe luis said on IRC that it was supposed to return non-nil on success, which I implemented in unified diff http://csserver.evansville.edu/~sc87/cffi/load-foreign-library-answers-nil.p...
The other possibility, changing t-f-l-a to ignore l-f-l's return value, is implemented in darcs patch tfla-success.patch in the same directory.
Thanks also for the kind word on the tutorial.
Here's a variant of my recent patch. Even uglier, but now the caching and creation of funcallables happens at macro-expansion time already. Don't know if this is still sane, gotta go to bed now... :)
James, I have you on Cc because I think c-l.net is supposed to be down tonight. This way at least /someone/ gets the email before it dissolves into the ether.
Cheers, Edi.
Edi Weitz edi@agharta.de writes:
Here's a variant of my recent patch. Even uglier, but now the caching and creation of funcallables happens at macro-expansion time already. Don't know if this is still sane, gotta go to bed now... :)
As you may have noticed, I've pushed your patch. However, I did some more testing afterwards and noticed that it didn't work very well. For some reason related to RT the foreign-funcall tests didn't reflect this but I pushed a new test (FUNCALL.INT.2) that failed.
I fixed it by having the %foreign-funcall expansion call get-foreign-funcallable at run-time and also at macroexpansion time. Let me know if you have a better idea.
Anyway, thanks for your patch!
On Sat, 21 Jan 2006 03:03:13 +0000, Luís Oliveira luismbo@gmail.com wrote:
As you may have noticed, I've pushed your patch. However, I did some more testing afterwards and noticed that it didn't work very well. For some reason related to RT the foreign-funcall tests didn't reflect this but I pushed a new test (FUNCALL.INT.2) that failed.
I fixed it by having the %foreign-funcall expansion call get-foreign-funcallable at run-time and also at macroexpansion time. Let me know if you have a better idea.
Yeah, an oversight of mine - thanks for fixing that. I can't come up with a better idea right now but I'll keep it in mind.
Cheers, Edi.
Edi Weitz edi@agharta.de writes:
I fixed it by having the %foreign-funcall expansion call get-foreign-funcallable at run-time and also at macroexpansion time. Let me know if you have a better idea.
Yeah, an oversight of mine - thanks for fixing that. I can't come up with a better idea right now but I'll keep it in mind.
I wrapped get-foreign-funcallable in a load-time-value. I remember James suggesting this when he first looked at your patch. I have no idea why I didn't try this first.