2008/4/7 Chun Tian (binghe) <[EMAIL PROTECTED]>:
>  Seems good:
>
>  CL-USER 3 > (cffi:with-foreign-object (x :long-long)
>
>    (setf (cffi:mem-ref x :long-long) 42)
>    (cffi:mem-ref x :long-long))
>  42

Ah, silly me. :long-long is the same size as :long on x86-64. We have
to treat :long differently in the compiler macros as well. The
attached patch should work better this time.

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
--- old-cffi+lotsastuff/src/cffi-lispworks.lisp	2008-04-07 02:29:59.000000000 +0100
+++ new-cffi+lotsastuff/src/cffi-lispworks.lisp	2008-04-07 02:29:59.000000000 +0100
@@ -64,7 +64,7 @@
 
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (mapc (lambda (feature) (pushnew feature *features*))
-        '(cffi-features:no-long-long)))
+        '(#-lispworks-64bit cffi-features:no-long-long)))
 
 ;;;# Symbol Case
 
@@ -147,27 +147,32 @@
 (defun convert-foreign-type (cffi-type)
   "Convert a CFFI type keyword to an FLI type."
   (ecase cffi-type
-    (:char            :byte)
-    (:unsigned-char   '(:unsigned :byte))
-    (:short           :short)
-    (:unsigned-short  '(:unsigned :short))
-    (:int             :int)
-    (:unsigned-int    '(:unsigned :int))
-    (:long            :long)
-    (:unsigned-long   '(:unsigned :long))
-    (:float           :float)
-    (:double          :double)
-    (:pointer         :pointer)
-    (:void            :void)))
+    (:char               :byte)
+    (:unsigned-char      '(:unsigned :byte))
+    (:short              :short)
+    (:unsigned-short     '(:unsigned :short))
+    (:int                :int)
+    (: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)
+    (:void               :void)))
 
 ;;; 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))
 (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)))
@@ -178,13 +183,20 @@
     (setf ptr (inc-pointer ptr offset)))
   (fli:dereference ptr :type (convert-foreign-type type)))
 
+;; Lispworks 5.0 on 64-bit platforms doesn't have [u]int64 support in
+;; FOREIGN-TYPED-AREF.  That was implemented in 5.1.
+#+(and lispworks-64bit lispworks5.0)
+(defun 64-bit-type-p (type)
+  (member type '(:long :unsigned-long :long-long :unsigned-long-long)))
+
 ;;; 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))
 (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 #+(and lispworks-64bit lispworks5.0) (64-bit-type-p type)
+                (eql type :pointer))
             (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))
@@ -217,7 +229,8 @@
   (if (constantp type)
       (once-only (val)
         (let ((type (eval type)))
-          (if (eql type :pointer)
+          (if (or #+(and lispworks-64bit lispworks5.0) (64-bit-type-p type)
+                  (eql type :pointer))
               (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))

_______________________________________________
cffi-devel mailing list
cffi-devel@common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel

Reply via email to