Re: should ccl allow ffi callbacks to be defined within closures
Ron Garret <[email protected]> Wed, 22 May 2024 08:06:03 -0700
| Newsgroups | gmane.lisp.openmcl.devel |
|---|---|
| Message-ID | <[email protected]> |
The problem here is not that callbacks cannot be closures. They can: ? (let ((x 1)) (defcallback foo () x)) FOO The problem is that they have to be defined at the top level, not by a = run-time call to DEFCALLBACK. The reason for that is that DEFCALLBACK = creates the callback function using CCL::NLAMBDA, which is like LAMBDA = except that the created function has a name attached to it: ? (function-name (lambda () t)) NIL ? (function-name (ccl::nlambda foo () t)) FOO The FFI needs that name to do its thing, and that name has to be a = symbol. The problem is that when NLAMBDA is called inside another = function rather than at the top-level, the name of the function that = gets created is a list, not a symbol: ? (defun baz () (function-name (ccl::nlambda foo () t))) BAZ ? (baz) (:INTERNAL FOO BAZ) and the FFI doesn't know how to handle that. rg > On May 21, 2024, at 11:48 PM, Madhu <[email protected]> wrote: >=20 > I came across a use of cffi callbacks which defines the callback > within a function. In CCL the following >=20 > ``` > (defun barf () > (ccl:defcallback CMPSTRINGP (:address p1 :address p2 :signed-int) > (ccl:external-call "strcmp" :address p1 :address p2 = :signed-int))) > (barf) >=20 > =3D> > Condition of type TYPE-ERROR: >=20 > The value (:INTERNAL CMPSTRINGP BARF) is not of the expected type > (AND SYMBOL (NOT (SATISFIES CONSTANTP))) > ``` >=20 > Is there any reason to disallow callbacks defined by defcallbacks from > being closures which capture their environment? >=20 > I am attaching a patch which continues to use the name specified by > DEFCALLBACK even if the defining function is a closure. >=20 > I'd very much appreciate it if other developers could review it and > give feedback. >=20 >=20 > =46rom d6241c160cc42979da2629862f97c350615850a9 Mon Sep 17 00:00:00 = 2001 > From: Madhu <[email protected]> > Date: Sun, 12 May 2024 22:01:08 +0530 > Subject: [PATCH] allow ffi callbacks to be defined within closures. >=20 > * level-1/l1-callbacks.lisp: (define-callback-function): If the > function-name is an internal-function of the form (:internal name) use > the internal name instead. >=20 > After this patch, defcallbacks can be defined within internal > functions. e.g. the following will work, instead of erroring out on > the name. >=20 > ``` > (defun barf () > (ccl:defcallback CMPSTRINGP (:address p1 :address p2 :signed-int) > (ccl:external-call "strcmp" :address p1 :address p2 = :signed-int))) > (barf) > ``` > --- > level-1/l1-callbacks.lisp | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) >=20 > diff --git a/level-1/l1-callbacks.lisp b/level-1/l1-callbacks.lisp > index 3f88041..f147f71 100644 > --- a/level-1/l1-callbacks.lisp > +++ b/level-1/l1-callbacks.lisp > @@ -25,7 +25,10 @@ (defstatic *callback-lock* (make-lock)) > (defun define-callback-function (lisp-function &optional doc-string = (without-interrupts t) info &aux name trampoline) > (unless (functionp lisp-function) > (setq lisp-function (require-type lisp-function 'function))) > - (unless (and (symbolp (setq name (function-name lisp-function))) > + (if (and (consp (setq name (function-name lisp-function))) > + (eql (car name) :internal)) > + (setq name (second name))) > + (unless (and (symbolp name) > ;;Might as well err out now before do any _Newptr's... > (not (constant-symbol-p name))) > (report-bad-arg name '(and symbol (not (satisfies constantp))))) > --=20 > 2.39.2.101.g768bb238c4 >=20