[cffi-devel] [Patch] LispWorks 5.0 and amd64 support
Hi, CFFI Developers I'm sorry to point this again. LispWorks 5.0 already support long-long foreign type, but their FOREIGN-TYPED-AREF doesn't support 64bit yet. So a patch is necessary, like attach. Thanks. #! /bin/sh /usr/share/dpatch/dpatch-run ## 10_lispworks.dpatch by <binghe@localhost.localdomain> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ diff -urNad cffi-20070901~/src/cffi-lispworks.lisp cffi-20070901/src/cffi-lispworks.lisp --- cffi-20070901~/src/cffi-lispworks.lisp 2007-09-22 16:19:19.000000000 +0800 +++ cffi-20070901/src/cffi-lispworks.lisp 2007-09-22 16:20:03.000000000 +0800 @@ -65,12 +65,14 @@ (eval-when (:compile-toplevel :load-toplevel :execute) (mapc (lambda (feature) (pushnew feature *features*)) '(;; Backend mis-features. + #-lispworks5 cffi-features:no-long-long ;; OS/CPU features. #+darwin cffi-features:darwin #+unix cffi-features:unix #+win32 cffi-features:windows #+harp::pc386 cffi-features:x86 + #+harp::amd64 cffi-features:x86-64 #+harp::powerpc cffi-features:ppc32 ))) @@ -163,6 +165,10 @@ (:unsigned-int '(:unsigned :int)) (:long :long) (:unsigned-long '(:unsigned :long)) + #+lispworks5 + (:long-long '(:long :long)) + #+lispworks5 + (:unsigned-long-long '(:unsigned :long :long)) (:float :float) (:double :double) (:pointer :pointer) @@ -170,7 +176,7 @@ ;;; Convert a CFFI type keyword to a symbol suitable for passing to ;;; FLI:FOREIGN-TYPED-AREF. -#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and lispworks-32bit) '(or)) (defun convert-foreign-typed-aref-type (cffi-type) (ecase cffi-type ((:char :short :int :long) @@ -188,7 +194,7 @@ ;;; In LispWorks versions where FLI:FOREIGN-TYPED-AREF is fbound, use ;;; it instead of FLI:DEREFERENCE in the optimizer for %MEM-REF. -#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and lispworks-32bit) '(or)) (define-compiler-macro %mem-ref (&whole form ptr type &optional (off 0)) (if (constantp type) (let ((type (eval type))) @@ -204,7 +210,7 @@ ;;; Open-code the call to FLI:DEREFERENCE when TYPE is constant at ;;; macroexpansion time, when FLI:FOREIGN-TYPED-AREF is not available. -#-#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#-#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and lispworks-32bit) '(or)) (define-compiler-macro %mem-ref (&whole form ptr type &optional (off 0)) (if (constantp type) (let ((ptr-form (if (eql off 0) ptr `(inc-pointer ,ptr ,off))) @@ -220,7 +226,7 @@ ;;; In LispWorks versions where FLI:FOREIGN-TYPED-AREF is fbound, use ;;; it instead of FLI:DEREFERENCE in the optimizer for %MEM-SET. -#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and lispworks-32bit) '(or)) (define-compiler-macro %mem-set (&whole form val ptr type &optional (off 0)) (if (constantp type) (once-only (val) @@ -239,7 +245,7 @@ ;;; Open-code the call to (SETF FLI:DEREFERENCE) when TYPE is constant ;;; at macroexpansion time. -#-#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#-#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and lispworks-32bit) '(or)) (define-compiler-macro %mem-set (&whole form val ptr type &optional (off 0)) (if (constantp type) (once-only (val)
Hello Tian, On 22/09/2007, Chun Tian (binghe) <binghe.lisp@gmail.com> wrote:
+ #-lispworks5 cffi-features:no-long-long
If possible, we should instead use one of the following approaches for checking whether Lispworks has long long support: * some feature keyword symbol specific to long long support, if Lispworks provides any. * check for version 5.0 or higher, presuming all platforms support long long as of version 5.0. (does Lispworks provide something like Allegro's :VERSION>=?) * programmatically check for long long support at read-time, i.e.: (eval-when (<always>) (unless (somehow-check-for-long-long-here) (pushnew 'cffi-features:no-long-long *features*))) If you could modify the patch to use one of these alternative approaches, that would be great. Thanks. -- Luís Oliveira http://student.dei.uc.pt/~lmoliv/
Luís Oliveira wrote:
Hello Tian,
On 22/09/2007, Chun Tian (binghe) <binghe.lisp@gmail.com> wrote:
-+ #-lispworks5 cffi-features:no-long-long
If possible, we should instead use one of the following approaches for checking whether Lispworks has long long support:
* some feature keyword symbol specific to long long support, if Lispworks provides any.
* check for version 5.0 or higher, presuming all platforms support long long as of version 5.0. (does Lispworks provide something like Allegro's :VERSION>=?)
* programmatically check for long long support at read-time, i.e.: (eval-when (<always>) (unless (somehow-check-for-long-long-here) (pushnew 'cffi-features:no-long-long *features*)))
If you could modify the patch to use one of these alternative approaches, that would be great. Thanks.
You're right and I was wrong: 1. It seems that only 64bit LispWorks 5.0 has long-long support, not 32bit, and it's undocumented. 2. the feature :lispworks-32bit does not exist in versions prior to 5.0, so I cannot use it to detect FOREIGN-TYPED-AREF. The long-long support maybe detect using (fli::64bit-long-p), I found this function in both 4.4 and 5.0 version of lispworks. So I think maybe these #+lispworks5 and #-lispworks5 can be replaced with #+#.(cl:if (fli::64bit-long-p) '(and) '(or)), etc. Another problem is that LispWorks's FOREIGN-TYPED-AREF cannot accept the type | (unsigned-byte 64)| and |(signed-byte 64) now, though people from LispWorks, Ltd say they will support this in next version. It's quite hard for me to give a patch which can still use other type on |FOREIGN-TYPED-AREF on platform support long-long, and this patch should also consider the future version of lispworks which can support | (unsigned-byte 64)| and |(signed-byte 64). And, I think |Lispworks didn't provide something like Allegro's :VERSION>=?), but seems LispWorks put its version in *features*, and LispWorks's version change is much small than Allegro, so the same detect maybe done with combined #+. If Martin Simmons see this post, I hope he can give us a better answer. | Thanks. |Chun Tian (binghe)
On Sat, 22 Sep 2007 21:57:13 +0800, Chun Tian (binghe) said:
Luís Oliveira wrote:
Hello Tian,
On 22/09/2007, Chun Tian (binghe) <binghe.lisp@gmail.com> wrote:
-+ #-lispworks5 cffi-features:no-long-long
If possible, we should instead use one of the following approaches for checking whether Lispworks has long long support:
* some feature keyword symbol specific to long long support, if Lispworks provides any.
* check for version 5.0 or higher, presuming all platforms support long long as of version 5.0. (does Lispworks provide something like Allegro's :VERSION>=?)
* programmatically check for long long support at read-time, i.e.: (eval-when (<always>) (unless (somehow-check-for-long-long-here) (pushnew 'cffi-features:no-long-long *features*)))
If you could modify the patch to use one of these alternative approaches, that would be great. Thanks.
You're right and I was wrong:
1. It seems that only 64bit LispWorks 5.0 has long-long support, not 32bit, and it's undocumented. 2. the feature :lispworks-32bit does not exist in versions prior to 5.0, so I cannot use it to detect FOREIGN-TYPED-AREF.
The long-long support maybe detect using (fli::64bit-long-p), I found this function in both 4.4 and 5.0 version of lispworks. So I think maybe these #+lispworks5 and #-lispworks5 can be replaced with #+#.(cl:if (fli::64bit-long-p) '(and) '(or)), etc.
Another problem is that LispWorks's FOREIGN-TYPED-AREF cannot accept the type | (unsigned-byte 64)| and |(signed-byte 64) now, though people from LispWorks, Ltd say they will support this in next version. It's quite hard for me to give a patch which can still use other type on |FOREIGN-TYPED-AREF on platform support long-long, and this patch should also consider the future version of lispworks which can support | (unsigned-byte 64)| and |(signed-byte 64).
And, I think |Lispworks didn't provide something like Allegro's :VERSION>=?), but seems LispWorks put its version in *features*, and LispWorks's version change is much small than Allegro, so the same detect maybe done with combined #+.
If Martin Simmons see this post, I hope he can give us a better answer.
Testing FLI::64BIT-LONG-P is not right -- it is false on Windows x64, but that platform fully supports :long-long. Support for :long-long is available in the LispWorks 5.0 FLI: - On all 64-bit platforms. - For FLI:DEFINE-FOREIGN-FUNCTION on all 32-bit platforms. It is not avaliable in: - LispWorks 4. - For data access functions such as FLI:DEREFERENCE on 32-bit platforms. Because of this last restriction, if CFFI wants to support :long-long on 32-bit LispWorks platforms, then it can do it for DEFCFUN but not other APIs. A single cffi-feature is not enough to describe this, so it could just support it on 64-bit platforms by using #-lispworks-64bit to enable cffi-features:no-long-long. To avoid the bugs in FOREIGN-TYPED-AREF, I suggest something like this for the optimizers (untested): #+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) (define-compiler-macro %mem-ref (&whole form ptr type &optional (off 0)) (if (constantp type) (let ((type (eval type))) (if (or (eql type :pointer) #+(and :lispworks-64bit :lispworks5.0) (member type '(:long :unsigned-long :long-long :unsigned-long-long))) (let ((fli-type (convert-foreign-type type)) (ptr-form (if (eql off 0) ptr `(inc-pointer ,ptr ,off)))) `(fli:dereference ,ptr-form :type ',fli-type)) (let ((lisp-type (convert-foreign-typed-aref-type type))) `(locally (declare (optimize (speed 3) (safety 0))) (fli:foreign-typed-aref ',lisp-type ,ptr (the fixnum ,off)))))) form)) Hope that helps. -- Martin Simmons LispWorks Ltd http://www.lispworks.com/
Thanks for your tips Martin. On 24/09/2007, Martin Simmons <martin@lispworks.com> wrote:
Because of this last restriction, if CFFI wants to support :long-long on 32-bit LispWorks platforms, then it can do it for DEFCFUN but not other APIs. A single cffi-feature is not enough to describe this, so it could just support it on 64-bit platforms by using #-lispworks-64bit to enable cffi-features:no-long-long.
Tian, since I don't have access to 64-bit lispworks I guess you're on your own. If you come up with a patch, though, I'll gladly test it on 32-bit lispworks and apply it. -- Luís Oliveira http://student.dei.uc.pt/~lmoliv/
Thanks again to Martin Simmons. Luís Oliveira wrote:
Thanks for your tips Martin.
On 24/09/2007, Martin Simmons <martin@lispworks.com> wrote:
Because of this last restriction, if CFFI wants to support :long-long on 32-bit LispWorks platforms, then it can do it for DEFCFUN but not other APIs. A single cffi-feature is not enough to describe this, so it could just support it on 64-bit platforms by using #-lispworks-64bit to enable cffi-features:no-long-long.
Tian, since I don't have access to 64-bit lispworks I guess you're on your own. If you come up with a patch, though, I'll gladly test it on 32-bit lispworks and apply it.
Oliveira, As Martin Simmons' suggest, I made another patch which works for me on my 64-bit lispworks edition. Please review it and apply it as your wish, thanks. Chun Tian (binghe) #! /bin/sh /usr/share/dpatch/dpatch-run ## 10_lispworks.dpatch by <binghe@localhost.localdomain> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ diff -urNad cffi-20070901~/src/cffi-lispworks.lisp cffi-20070901/src/cffi-lispworks.lisp --- cffi-20070901~/src/cffi-lispworks.lisp 2007-09-25 13:01:10.000000000 +0800 +++ cffi-20070901/src/cffi-lispworks.lisp 2007-09-25 13:21:52.000000000 +0800 @@ -65,12 +65,14 @@ (eval-when (:compile-toplevel :load-toplevel :execute) (mapc (lambda (feature) (pushnew feature *features*)) '(;; Backend mis-features. + #-lispworks-64bit cffi-features:no-long-long ;; OS/CPU features. #+darwin cffi-features:darwin #+unix cffi-features:unix #+win32 cffi-features:windows #+harp::pc386 cffi-features:x86 + #+harp::amd64 cffi-features:x86-64 #+harp::powerpc cffi-features:ppc32 ))) @@ -163,6 +165,10 @@ (:unsigned-int '(:unsigned :int)) (:long :long) (:unsigned-long '(:unsigned :long)) + #+lispworks-64bit + (:long-long '(:long :long)) + #+lispworks-64bit + (:unsigned-long-long '(:unsigned :long :long)) (:float :float) (:double :double) (:pointer :pointer) @@ -173,9 +179,10 @@ #+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) (defun convert-foreign-typed-aref-type (cffi-type) (ecase cffi-type - ((:char :short :int :long) + ((:char :short :int :long #+lispworks-64bit :long-long) `(signed-byte ,(* 8 (%foreign-type-size cffi-type)))) - ((:unsigned-char :unsigned-short :unsigned-int :unsigned-long) + ((:unsigned-char :unsigned-short :unsigned-int :unsigned-long + #+lispworks-64bit :unsigned-long-long) `(unsigned-byte ,(* 8 (%foreign-type-size cffi-type)))) (:float 'single-float) (:double 'double-float))) @@ -192,7 +199,10 @@ (define-compiler-macro %mem-ref (&whole form ptr type &optional (off 0)) (if (constantp type) (let ((type (eval type))) - (if (eql type :pointer) + (if (or (eql type :pointer) + #+(and lispworks-64bit lispworks5.0) + (member type '(:long :unsigned-long + :long-long :unsigned-long-long))) (let ((fli-type (convert-foreign-type type)) (ptr-form (if (eql off 0) ptr `(inc-pointer ,ptr ,off)))) `(fli:dereference ,ptr-form :type ',fli-type)) @@ -225,7 +235,10 @@ (if (constantp type) (once-only (val) (let ((type (eval type))) - (if (eql type :pointer) + (if (or (eql type :pointer) + #+(and lispworks-64bit lispworks5.0) + (member type '(:long :unsigned-long + :long-long :unsigned-long-long))) (let ((fli-type (convert-foreign-type type)) (ptr-form (if (eql off 0) ptr `(inc-pointer ,ptr ,off)))) `(setf (fli:dereference ,ptr-form :type ',fli-type) ,val))
Luís Oliveira wrote:
Hello Tian,
On 22/09/2007, Chun Tian (binghe) <binghe.lisp@gmail.com> wrote:
+ #-lispworks5 cffi-features:no-long-long
If possible, we should instead use one of the following approaches for checking whether Lispworks has long long support:
* some feature keyword symbol specific to long long support, if Lispworks provides any.
* check for version 5.0 or higher, presuming all platforms support long long as of version 5.0. (does Lispworks provide something like Allegro's :VERSION>=?)
* programmatically check for long long support at read-time, i.e.: (eval-when (<always>) (unless (somehow-check-for-long-long-here) (pushnew 'cffi-features:no-long-long *features*)))
If you could modify the patch to use one of these alternative approaches, that would be great. Thanks.
Attach is a modified patch which I use now, using (fli::64bit-long-p). #! /bin/sh /usr/share/dpatch/dpatch-run ## 10_lispworks.dpatch by <binghe@localhost.localdomain> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ diff -urNad cffi-20070901~/src/cffi-lispworks.lisp cffi-20070901/src/cffi-lispworks.lisp --- cffi-20070901~/src/cffi-lispworks.lisp 2007-09-22 22:33:06.000000000 +0800 +++ cffi-20070901/src/cffi-lispworks.lisp 2007-09-22 22:35:58.000000000 +0800 @@ -65,12 +65,14 @@ (eval-when (:compile-toplevel :load-toplevel :execute) (mapc (lambda (feature) (pushnew feature *features*)) '(;; Backend mis-features. + #-#.(cl:if (fli::64bit-long-p) '(and) '(or)) cffi-features:no-long-long ;; OS/CPU features. #+darwin cffi-features:darwin #+unix cffi-features:unix #+win32 cffi-features:windows #+harp::pc386 cffi-features:x86 + #+harp::amd64 cffi-features:x86-64 #+harp::powerpc cffi-features:ppc32 ))) @@ -163,6 +165,10 @@ (:unsigned-int '(:unsigned :int)) (:long :long) (:unsigned-long '(:unsigned :long)) + #+#.(cl:if (fli::64bit-long-p) '(and) '(or)) + (:long-long '(:long :long)) + #+#.(cl:if (fli::64bit-long-p) '(and) '(or)) + (:unsigned-long-long '(:unsigned :long :long)) (:float :float) (:double :double) (:pointer :pointer) @@ -170,7 +176,8 @@ ;;; Convert a CFFI type keyword to a symbol suitable for passing to ;;; FLI:FOREIGN-TYPED-AREF. -#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#+#.(cl:if (cl:and (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") + (cl:not (fli::64bit-long-p))) '(and) '(or)) (defun convert-foreign-typed-aref-type (cffi-type) (ecase cffi-type ((:char :short :int :long) @@ -188,7 +195,8 @@ ;;; In LispWorks versions where FLI:FOREIGN-TYPED-AREF is fbound, use ;;; it instead of FLI:DEREFERENCE in the optimizer for %MEM-REF. -#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#+#.(cl:if (cl:and (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") + (cl:not (fli::64bit-long-p))) '(and) '(or)) (define-compiler-macro %mem-ref (&whole form ptr type &optional (off 0)) (if (constantp type) (let ((type (eval type))) @@ -204,7 +212,8 @@ ;;; Open-code the call to FLI:DEREFERENCE when TYPE is constant at ;;; macroexpansion time, when FLI:FOREIGN-TYPED-AREF is not available. -#-#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#-#.(cl:if (cl:and (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") + (cl:not (fli::64bit-long-p))) '(and) '(or)) (define-compiler-macro %mem-ref (&whole form ptr type &optional (off 0)) (if (constantp type) (let ((ptr-form (if (eql off 0) ptr `(inc-pointer ,ptr ,off))) @@ -220,7 +229,8 @@ ;;; In LispWorks versions where FLI:FOREIGN-TYPED-AREF is fbound, use ;;; it instead of FLI:DEREFERENCE in the optimizer for %MEM-SET. -#+#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#+#.(cl:if (cl:and (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") + (cl:not (fli::64bit-long-p))) '(and) '(or)) (define-compiler-macro %mem-set (&whole form val ptr type &optional (off 0)) (if (constantp type) (once-only (val) @@ -239,7 +249,8 @@ ;;; Open-code the call to (SETF FLI:DEREFERENCE) when TYPE is constant ;;; at macroexpansion time. -#-#.(cl:if (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") '(and) '(or)) +#-#.(cl:if (cl:and (cl:find-symbol "FOREIGN-TYPED-AREF" "FLI") + (cl:not (fli::64bit-long-p))) '(and) '(or)) (define-compiler-macro %mem-set (&whole form val ptr type &optional (off 0)) (if (constantp type) (once-only (val)
participants (3)
-
Chun Tian (binghe)
-
Luís Oliveira
-
Martin Simmons