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:
- 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.