Greetings all,
I first sent this message to SBCL-bugs, since the code works on CCL. where they suggested it's an issue in CFFI. I'm hoping that someone here has an idea of what the problem is.
I'm
wrapping some of the complex math functions in openlibm, and encounter the following stack trace when calling them:
The value
NIL
is not of type
SB-SYS:SYSTEM-AREA-POINTER
when binding SB-ALIEN::VALUE
...
0: (CFFI::LIBFFI/CALL #.(SB-SYS:INT-SAP #X027C0610) NIL #.(SB-SYS:INT-SAP #X0574FFE0) #.(SB-SYS:INT-SAP #X0574FFF0))
Locals:
AVALUES = #.(SB-SYS:INT-SAP #X0574FFF0)
FFI-CIF = #.(SB-SYS:INT-SAP #X027C0610)
FUNCTION = NIL
RVALUE = #.(SB-SYS:INT-SAP #X0574FFE0)
The
FUNCTION parameter, which SBCL expects to be a INT-SAP, is NIL. All the
other (non complex number) functions work, but those going through the
foreign-memory functions fail.
Openlibm
is is available on any linux distribution via the package manager, and
on MS Windows via MSYS2. This is with SBCL 2.0.10 on MS Windows 10.To
reproduce the issue:
(ql:quickload '(:cffi :cffi-libffi))
(cffi:define-foreign-library libm
;; (:windows (:or "libopenlibm"
;; #.(cl:merge-pathnames "libopenlibm.dll" cl:*compile-file-pathname*)))
(t (:default "libopenlibm")))
(cffi:load-foreign-library 'libm)
#+unix
(cffi:define-foreign-library libm
(t (:default "libopenlibm")))
(cffi:defcstruct (complex-double-c :class complex-double-type)
(dat :double :count 2))
(cl:defmethod cffi:translate-into-foreign-memory ((value cl:complex) (type complex-double-type) p)
(cffi:with-foreign-slots ((dat) p (:struct complex-double-c))
(cl:setf (cffi:mem-aref dat :double 0) (cl:realpart value)
(cffi:mem-aref dat :double 1) (cl:imagpart value))))
(cl:defmethod cffi:translate-from-foreign (p (type complex-double-type))
(cffi:with-foreign-slots ((dat) p (:struct complex-double-c))
(cl:complex (cffi:mem-aref dat :double 0)
(cffi:mem-aref dat :double 1))))
(cffi:defcfun "cacos" (:struct complex-double-c) (c (:struct complex-double-c)))
;;; Try to call the function via CFFI
(cacos #C(0.16340015462715485d0 0.35359829928359165d0))
;;; Lower level version of the above
(cl:defun complex-acos (c)
(cffi:foreign-funcall "casos"
(:struct complex-double-c) c (:struct complex-double-c)))
(complex-acos #C(0.16340015462715485d0 0.35359829928359165d0))
Any ideas?