summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-11 20:02:12 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-11 20:02:12 -0700
commite43849b3f941b12e14571aa09a5c18c3e105440f (patch)
tree335134dcf4b2093519eec949f2658e49821fbb53 /txr.1
parent1b615a6667660b353c7719d805a0a40cdd948789 (diff)
downloadtxr-e43849b3f941b12e14571aa09a5c18c3e105440f.tar.gz
txr-e43849b3f941b12e14571aa09a5c18c3e105440f.tar.bz2
txr-e43849b3f941b12e14571aa09a5c18c3e105440f.zip
ffi: support programmable abort return value.
* ffi.c (stuct txr_ffi_closure): New member, abort_retval. (ffi_closure_mark_op): Mark the new member. (ffi_closure_dispatch_safe): Implement the abort_retval. If it is not nil, use put to place the value into the return buffer. There is a risk that this could also throw an exception, which is no longer protected: programer's problem. (ffi_make_closure): New abort_ret_in argument, which is defaulted and stored. (ffi_init): Update registration of ffi-make-closure to reflect new argument. * ffi.h (ffi_make_closure): Declaration updated. * share/txr/stdlib/ffi.tl (sys:deffi-cb-expander): Add abort-retval parameter; insert into ffi-make-closure call. (deffi-cb): Take optional abort-retval expression; pass it down to the expander function. (deffi-cb-unsafe): Pass nil as abort-retval down to expander. * txr.1: Documented.
Diffstat (limited to 'txr.1')
-rw-r--r--txr.132
1 files changed, 27 insertions, 5 deletions
diff --git a/txr.1 b/txr.1
index 5bc7fecd..ccb5f611 100644
--- a/txr.1
+++ b/txr.1
@@ -54048,7 +54048,8 @@ argument types match.
.coNP Function @ ffi-make-closure
.synb
-.mets (ffi-make-closure < lisp-fun < call-desc <> [ safe-p ])
+.mets (ffi-make-closure < lisp-fun < call-desc
+.mets \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ >> [ safe-p <> [ abort-val ]])
.syne
.desc
The
@@ -54094,7 +54095,12 @@ the control transfer when the foreign code itself finishes and returns.
If the callback returns a value (its return type is other than
.codn void )
then in this situation, the callback returns an all-zero-bits return
-value to the foreign caller.
+value to the foreign caller. If the
+.meta abort-val
+parameter is specified and its value is other than
+.codn nil ,
+then that value will be used as the return value instead of an all-zero
+bit pattern.
An unsafely dispatched closure permits the capture of continuations from
the callback across the foreign code and direct dynamic control transfers which
@@ -54388,7 +54394,7 @@ as its value.
.coNP Macros @ deffi-cb and @ deffi-cb-unsafe
.synb
-.mets (deffi-cb < name < rettype << argtypes )
+.mets (deffi-cb < name < rettype < argtypes <> [ abort-val ])
.mets (deffi-cb-unsafe < name < rettype << argtypes )
.syne
.desc
@@ -54425,18 +54431,34 @@ The generated function called
then serves as a combinator which takes a Lisp function as its argument,
and binds it to the FFI call descriptor to produce a FFI closure.
That closure may then be passed to foreign functions as a callback.
+The
+.code deffi-cb
+macro generates a callback which uses safe dispatch, which is explained
+in the description of the
+.code ffi-make-callback
+function. The optional
+.meta abort-val
+parameter specifies an expression which evaluates to the value
+to be returned by the callback in the event that a dynamic control
+transfer is intercepted. The purpose of this value is to indicate
+to the foreign code that the callback wishes to abort operation;
+it is useful in situations when a suitable return value will induce
+the foreign code to co-operate and itself return to the Lisp code
+which will then continue the dynamic control transfer.
The
.code deffi-cb-unsafe
macro is a variant of
.code deffi-cb
-with exactly the same conventions. The difference is that it arranges for
+with the same argument conventions. The difference is that it arranges for
.code ffi-make-closure
to be invoked with
.code nil
for the
.meta safe-p
-parameter.
+parameter. This macro has no
+.meta abort-val
+parameter, since unsafe callbacks do not use it.
.TP* Example: