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

Reply via email to