Jan Rychter <[EMAIL PROTECTED]> writes: >>>>>> "Luís" == Luís Oliveira <[EMAIL PROTECTED]> writes: > Luís> I'm pretty sure we could support anonymous callbacks, on SBCL and > Luís> CLISP anyway. Do any other Lisps support this?
> So, perhaps it is worth implementing as an optional feature. Hopefully > other implementations will follow suit. I took a shot at implementing this on SBCL and CLISP (I don't have a working ECL installation), here's the patch:
New patches: [First cut at an implementation of CALLBACK-LAMBDA. James Bielman <[EMAIL PROTECTED]>**20060205220941 - Only supported so far on SBCL and CLISP. - There is no way yet to free the callback functions if this is needed. - Add the feature CFFI-FEATURES:NO-CALLBACK-LAMBDA if not supported. ] { hunk ./src/cffi-allegro.lisp 66 + cffi-features:no-callback-lambda hunk ./src/cffi-clisp.lisp 54 - #:%callback)) + #:%callback + #:%callback-lambda)) hunk ./src/cffi-clisp.lisp 304 +;;; Define an anonymous callback which may close over the lexical +;;; environment. Returns a pointer that may be passed to a foreign +;;; function. +(defmacro %callback-lambda (rettype arg-names arg-types &body body) + (let ((type (callback-type rettype arg-names arg-types))) + `(ffi:with-foreign-object (ptr 'ffi:c-pointer) + (setf (ffi:memory-as ptr ,type) + (lambda ,arg-names ,@body)) + (ffi:foreign-value ptr)))) + hunk ./src/cffi-cmucl.lisp 63 - '(;; OS/CPU features. + '(;; Backend mis-features. + cffi-features:no-callback-lambda + ;; OS/CPU features. hunk ./src/cffi-corman.lisp 65 + cffi-features:no-callback-lambda hunk ./src/cffi-ecl.lisp 63 + cffi-features:no-callback-lambda hunk ./src/cffi-lispworks.lisp 66 + cffi-features:no-callback-lambda hunk ./src/cffi-openmcl.lisp 63 - '(;; OS/CPU features. + '(;; Backend mis-features. + cffi-features:no-callback-lambda + ;; OS/CPU features. hunk ./src/cffi-sbcl.lisp 55 - #:%callback)) + #:%callback + #:%callback-lambda)) hunk ./src/cffi-sbcl.lisp 289 +;;; Define an anonymous callback which may close over the lexical +;;; environment. Returns a pointer that may be passed to a foreign +;;; function. +(defmacro %callback-lambda (rettype arg-names arg-types &body body) + `(alien-sap + (sb-alien::alien-lambda ,(convert-foreign-type rettype) + ,(mapcar (lambda (sym type) + (list sym (convert-foreign-type type))) + arg-names arg-types) + ,@body))) + hunk ./src/features.lisp 41 + #:no-callback-lambda hunk ./src/functions.lisp 214 + +;;; Define an anonymous callback which may close over its lexical +;;; environment. Returns a pointer which may be passed as a function +;;; pointer to foreign functions. There is currently no way to free +;;; the returned function (if necessary). +#-cffi-features:no-callback-lambda +(defmacro callback-lambda (return-type args &body body) + (let ((arg-names (mapcar #'car args)) + (arg-types (mapcar #'cadr args))) + `(%callback-lambda ,(canonicalize-foreign-type return-type) + ,arg-names ,(mapcar #'canonicalize-foreign-type arg-types) + (inverse-translate-objects ,arg-names ,arg-types ,return-type + ,@body)))) } Context: [TAG 0.9.0 James Bielman <[EMAIL PROTECTED]>**20060204082912] Patch bundle hash: 41e14a50446f547a9f3d2bd1f18c4cdebb9f20d3
This still needs unit tests but cursory testing from the REPL looks good---please give it a try. James
_______________________________________________ cffi-devel mailing list cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel