diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-01-16 06:20:12 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-01-16 06:20:12 -0800 |
commit | 2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f (patch) | |
tree | 718b44f3053dfaeb9feb60b3828790fed0f5647f | |
parent | 05b1383fae022cea0548ed9c587c4a1289c6b1e6 (diff) | |
download | txr-2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f.tar.gz txr-2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f.tar.bz2 txr-2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f.zip |
ffi: diagnose missing with-dyn-lib.
If the programmer writes a deffi, deffi-sym or deffi-var that
makes simple references, and that macro is not wrapped in
with-dyn-lib, an unhelpful error message results about
sys:ffi-lib being unbound. We can detect this situation and
provide a warning.
* share/txr/stdlib/ffi.tl (sys:with-dyn-lib-check,
sys:expand-sym-ref): New functions.
(deffi, deffi-sym, deffi-var): Capture environment parameter.
Common code replaced by call to sys:expand-sym-ref, where the
missing sys:ffi-lib situation is diagnosed. This is only done
in cases when the simple reference syntax occurs.
-rw-r--r-- | share/txr/stdlib/ffi.tl | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/share/txr/stdlib/ffi.tl b/share/txr/stdlib/ffi.tl index 99992bc5..bc6c207f 100644 --- a/share/txr/stdlib/ffi.tl +++ b/share/txr/stdlib/ffi.tl @@ -37,6 +37,22 @@ (symacrolet ((sys:ffi-lib ,keep-var)) ,*body)))) +(defun sys:with-dyn-lib-check (f e ref) + (when (eq (macroexpand 'sys:ffi-lib e) 'sys:ffi-lib) + (compile-warning f "simple ref ~s requires ~s" + ref 'with-dyn-lib))) + +(defun sys:expand-sym-ref (f e exp) + (cond + ((stringp exp) + (sys:with-dyn-lib-check f e exp) + ^(dlsym-checked sys:ffi-lib ,exp)) + ((and (consp exp) (stringp (car exp))) + (mac-param-bind f (sym ver) exp + (sys:with-dyn-lib-check f e exp) + ^(dlvsym-checked sys:ffi-lib ,sym ,ver))) + (t exp))) + (defun sys:analyze-argtypes (form argtypes) (let ((p (posq : argtypes))) (when p @@ -45,14 +61,9 @@ (del [argtypes p]))) (list* (length argtypes) p argtypes))) -(defmacro deffi (:form f name fun-expr rettype argtypes) - (let ((fun-ref (cond - ((stringp fun-expr) - ^(dlsym-checked sys:ffi-lib ,fun-expr)) - ((consp fun-expr) - (mac-param-bind f (sym ver) fun-expr - ^(dlvsym-checked sys:ffi-lib ,sym ,ver))) - (t fun-expr))) + +(defmacro deffi (:form f :env e name fun-expr rettype argtypes) + (let ((fun-ref (sys:expand-sym-ref f e fun-expr)) (ret-type-sym (gensym "ret-type-")) (arg-types-sym (gensym "arg-types-")) (call-desc-sym (gensym "call-desc-")) @@ -96,26 +107,14 @@ (defmacro deffi-cb-unsafe (:form f name rettype argtypes) (sys:deffi-cb-expander f name rettype argtypes nil nil)) -(defmacro deffi-sym (:form f name var-expr : type-sym) - (let ((var-ref (cond - ((stringp var-expr) - ^(dlsym-checked sys:ffi-lib ,var-expr)) - ((consp var-expr) - (mac-param-bind f (sym ver) var-expr - ^(dlvsym-checked sys:ffi-lib ,sym ,ver))) - (t var-expr)))) +(defmacro deffi-sym (:form f :env e name var-expr : type-sym) + (let ((var-ref (sys:expand-sym-ref f e var-expr))) ^(defparml ,name ,(if type-sym ^(cptr-cast ',type-sym ,var-ref) var-ref)))) -(defmacro deffi-var (:form f name var-expr type) - (let ((var-ref (cond - ((stringp var-expr) - ^(dlsym-checked sys:ffi-lib ,var-expr)) - ((consp var-expr) - (mac-param-bind f (sym ver) var-expr - ^(dlvsym-checked sys:ffi-lib ,sym ,ver))) - (t var-expr))) +(defmacro deffi-var (:form f :env e name var-expr type) + (let ((var-ref (sys:expand-sym-ref f e var-expr)) (type-sym (gensym "type-")) (var-sym (gensym "var-"))) ^(progn |