summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-10 16:04:48 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-10 16:04:48 -0700
commit430e4c7082f89b75ca9fc5af11674392aaefdffb (patch)
tree5e6f6b57bb722362008e461de306ba0d1e85cadf /ffi.c
parent8720c828d956fd29d9266d0e06cb7ead69d5ab95 (diff)
downloadtxr-430e4c7082f89b75ca9fc5af11674392aaefdffb.tar.gz
txr-430e4c7082f89b75ca9fc5af11674392aaefdffb.tar.bz2
txr-430e4c7082f89b75ca9fc5af11674392aaefdffb.zip
ffi: retain some functionality if libffi missing.
The FFI module is more than just foreign calls and callbacks; it provides a type system and operations for working with binary data. None of it depends on libffi being present and so shouldn't be disabled if libffi is not available. * Makefile (ffi.o): Unconditionally link this object file, not subject to the have_libffi variable. * configure (have_libffi): Variable removed. (gen_config_make): Do not generate a have_libffi variable into config.make, since nothing needs it. * ffi.c (ffi_type): Fake ffi_type defined if libffi is missing. (FFI_TYPE_STRUCT): Fake macro. (ffi_type ffi_type_void, ffi_type_pointer, ffi_type_sint, ffi_type ffi_type_schar, ffi_type_uchar, ffi_type ffi_type_sshort, ffi_type_ushort, ffi_type ffi_type_sint, ffi_type_uint, ffi_type ffi_type_slong, ffi_type_ulong, ffi_type ffi_type_sint8, ffi_type_uint8, ffi_type ffi_type_sint16, ffi_type_uint16, ffi_type ffi_type_sint32, ffi_type_uint32, ffi_type ffi_type_sint64, ffi_type_uint64, ffi_type ffi_type_float, ffi_type_double): Fake libffi type objects, so that code which references these things will build without modification. (ffi_get_type): Function only defined if we have libffi. (ffi_type_struct_destroy_op, ffi_struct_clone, make_ffi_type_struct, ffi_array_clone, make_ffi_type_array): Don't work with ffi_type's element array if we don't have libffi; our fake ffi_type doesn't have such an array. (struct txr_ffi_closure): Type only defined if we have libffi. (ffi_closure_struct, ffi_closure_struct_checked, ffi_closure_print_op, ffi_closure_destroy_op, ffi_closure_mark_op, ffi_closure_put): Functions only defined if we have libffi. (ffi_closure_ops): Static structure only defined if we have libffi. (ffi_init_types): Don't register a closure type if we don't have libffi. (struct txr_ffi_call_desc): Don't define type if we don't have libffi. (ffi_call_desc, ffi_call_desc_checked, ffi_call_desc_print_op, ffi_call_desc_destroy_op, ffi_call_desc_mark_op, ffi_make_call_desc, ffi_call_wrap, ffi_closure_dispatch, ffi_closure_dispatch_safe, ffi_make_closure, ffi_closure_get_fptr): Functions only defined if we have libffi. (ffi_call_desc_ops): Static structure only defined if we have libffi. (ffi_init): Only register ffi-make-call-desc, ffi-call, and ffi-make-closure if we have libffi. * lib.c: Include "ffi.h" header unconditionally. (generic_funcall, ref, refset, int): Remove #if HAVE_LIBFFI.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/ffi.c b/ffi.c
index f0974ddf..aa4813df 100644
--- a/ffi.c
+++ b/ffi.c
@@ -36,8 +36,10 @@
#include <wchar.h>
#include <dirent.h>
#include <time.h>
-#include <ffi.h>
#include "config.h"
+#if HAVE_LIBFFI
+#include <ffi.h>
+#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -74,6 +76,12 @@
#define ifbe2(expr1, expr2) (expr1)
#endif
+#if !HAVE_LIBFFI
+typedef struct ffi_type {
+ char type, size;
+} ffi_type;
+#define FFI_TYPE_STRUCT 0
+#endif
val uint8_s, int8_s;
val uint16_s, int16_s;
@@ -122,7 +130,22 @@ val ffi_type_s, ffi_call_desc_s, ffi_closure_s;
static val ffi_typedef_hash;
+#if HAVE_LIBFFI
static uw_frame_t *s_exit_point;
+#endif
+
+#if !HAVE_LIBFFI
+static ffi_type ffi_type_void, ffi_type_pointer, ffi_type_sint;
+static ffi_type ffi_type_schar, ffi_type_uchar;
+static ffi_type ffi_type_sshort, ffi_type_ushort;
+static ffi_type ffi_type_sint, ffi_type_uint;
+static ffi_type ffi_type_slong, ffi_type_ulong;
+static ffi_type ffi_type_sint8, ffi_type_uint8;
+static ffi_type ffi_type_sint16, ffi_type_uint16;
+static ffi_type ffi_type_sint32, ffi_type_uint32;
+static ffi_type ffi_type_sint64, ffi_type_uint64;
+static ffi_type ffi_type_float, ffi_type_double;
+#endif
struct smemb {
val mname;
@@ -169,11 +192,13 @@ static struct txr_ffi_type *ffi_type_struct_checked(val obj)
return coerce(struct txr_ffi_type *, cobj_handle(obj, ffi_type_s));
}
+#if HAVE_LIBFFI
static ffi_type *ffi_get_type(val obj)
{
struct txr_ffi_type *tffi = ffi_type_struct_checked(obj);
return tffi->ft;
}
+#endif
static val ffi_get_lisp_type(val obj)
{
@@ -192,11 +217,17 @@ static void ffi_type_print_op(val obj, val out, val pretty, struct strm_ctx *ctx
static void ffi_type_struct_destroy_op(val obj)
{
struct txr_ffi_type *tft = ffi_type_struct(obj);
+#if HAVE_LIBFFI
ffi_type *ft = tft->ft;
+#endif
+
+#if HAVE_LIBFFI
free(ft->elements);
ft->elements = 0;
free(ft);
tft->ft = 0;
+#endif
+
free(tft->memb);
tft->memb = 0;
free(tft);
@@ -274,6 +305,8 @@ static struct cobj_ops ffi_type_enum_ops =
ffi_enum_type_mark,
cobj_eq_hash_op);
+#if HAVE_LIBFFI
+
struct txr_ffi_closure {
ffi_closure *clo;
mem_t *fptr;
@@ -329,6 +362,8 @@ static struct cobj_ops ffi_closure_ops =
ffi_closure_mark_op,
cobj_eq_hash_op);
+#endif
+
static void ffi_void_put(struct txr_ffi_type *tft, val n, mem_t *dst, val self)
{
}
@@ -1885,6 +1920,7 @@ static val ffi_buf_d_get(struct txr_ffi_type *tft, mem_t *src, val self)
return ret;
}
+#if HAVE_LIBFFI
static void ffi_closure_put(struct txr_ffi_type *tft, val ptr, mem_t *dst,
val self)
{
@@ -1903,6 +1939,7 @@ static void ffi_closure_put(struct txr_ffi_type *tft, val ptr, mem_t *dst,
memcpy(dst, &p, sizeof p);
}
+#endif
static val ffi_ptr_in_in(struct txr_ffi_type *tft, int copy, mem_t *src,
val obj, val self)
@@ -2667,15 +2704,19 @@ static struct txr_ffi_type *ffi_struct_clone(struct txr_ffi_type *orig)
{
cnum nmemb = orig->nelem;
struct txr_ffi_type *copy = ffi_simple_clone(orig);
+#if HAVE_LIBFFI
size_t elements_size = sizeof *orig->ft->elements * (nmemb + 1);
+#endif
size_t memb_size = sizeof *orig->memb * nmemb;
ffi_type *ft = coerce(ffi_type *, chk_copy_obj(coerce(mem_t *, orig->ft),
sizeof *orig->ft));
copy->ft = ft;
+#if HAVE_LIBFFI
ft->elements = coerce(ffi_type **, chk_copy_obj(coerce(mem_t *,
ft->elements),
elements_size));
+#endif
copy->memb = coerce(struct smemb *, chk_copy_obj(coerce(mem_t *,
orig->memb),
memb_size));
@@ -2691,8 +2732,10 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
ffi_type *ft = coerce(ffi_type *, chk_calloc(1, sizeof *ft));
cnum nmemb = c_num(length(types)), i;
+#if HAVE_LIBFFI
ffi_type **elements = coerce(ffi_type **,
chk_malloc(sizeof *elements * (nmemb + 1)));
+#endif
struct smemb *memb = coerce(struct smemb *,
chk_calloc(nmemb, sizeof *memb));
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
@@ -2724,7 +2767,9 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
struct txr_ffi_type *mtft = ffi_type_struct(type);
cnum size = mtft->size;
+#if HAVE_LIBFFI
elements[i] = mtft->ft;
+#endif
memb[i].mtype = type;
memb[i].mname = slot;
@@ -2800,12 +2845,16 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
tft->nelem = i;
+#if HAVE_LIBFFI
elements[i] = 0;
+#endif
if (need_out_handler)
tft->out = ffi_struct_out;
+#if HAVE_LIBFFI
ft->elements = elements;
+#endif
tft->size = (offs + most_align - 1) & ~(most_align - 1);
tft->align = most_align;
@@ -2815,16 +2864,20 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
static struct txr_ffi_type *ffi_array_clone(struct txr_ffi_type *orig)
{
- cnum nmemb = orig->nelem;
struct txr_ffi_type *copy = ffi_simple_clone(orig);
+#if HAVE_LIBFFI
+ cnum nmemb = orig->nelem;
size_t elements_size = sizeof *orig->ft->elements * (nmemb + 1);
+#endif
ffi_type *ft = coerce(ffi_type *, chk_copy_obj(coerce(mem_t *, orig->ft),
sizeof *orig->ft));
copy->ft = ft;
+#if HAVE_LIBFFI
ft->elements = coerce(ffi_type **, chk_copy_obj(coerce(mem_t *,
ft->elements),
elements_size));
+#endif
return copy;
}
@@ -2836,8 +2889,10 @@ static val make_ffi_type_array(val syntax, val lisp_type,
ffi_type *ft = coerce(ffi_type *, chk_calloc(1, sizeof *ft));
cnum nelem = c_num(dim), i;
+#if HAVE_LIBFFI
ffi_type **elements = coerce(ffi_type **, chk_malloc(sizeof *elements *
(nelem + 1)));
+#endif
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
struct txr_ffi_type *etft = ffi_type_struct(eltype);
@@ -2858,7 +2913,9 @@ static val make_ffi_type_array(val syntax, val lisp_type,
tft->free = free;
for (i = 0; i < nelem; i++) {
+#if HAVE_LIBFFI
elements[i] = etft->ft;
+#endif
if (i == 0) {
tft->size = etft->size * nelem;
tft->align = etft->align;
@@ -2867,9 +2924,11 @@ static val make_ffi_type_array(val syntax, val lisp_type,
}
}
+#if HAVE_LIBFFI
elements[i] = 0;
ft->elements = elements;
+#endif
tft->nelem = nelem;
@@ -3579,12 +3638,15 @@ static void ffi_init_types(void)
}
}
+#if HAVE_LIBFFI
ffi_typedef(closure_s, make_ffi_type_builtin(closure_s, fun_s,
sizeof (mem_t *),
alignof (mem_t *),
&ffi_type_pointer,
ffi_closure_put, ffi_cptr_get,
0, 0));
+#endif
+
ffi_typedef(void_s, make_ffi_type_builtin(void_s, null_s, 0, 0,
&ffi_type_void,
ffi_void_put, ffi_void_get,
@@ -3687,6 +3749,8 @@ static void ffi_init_extra_types(void)
#endif
}
+#if HAVE_LIBFFI
+
struct txr_ffi_call_desc {
ffi_cif cif;
ffi_type **args;
@@ -4020,6 +4084,8 @@ mem_t *ffi_closure_get_fptr(val closure)
return tfcl->fptr;
}
+#endif
+
val ffi_typedef(val name, val type)
{
val self = lit("ffi-typedef");
@@ -4539,9 +4605,11 @@ void ffi_init(void)
ffi_call_desc_s = intern(lit("ffi-call-desc"), user_package);
ffi_closure_s = intern(lit("ffi-closure"), user_package);
reg_fun(intern(lit("ffi-type-compile"), user_package), func_n1(ffi_type_compile));
+#if HAVE_LIBFFI
reg_fun(intern(lit("ffi-make-call-desc"), user_package), func_n4(ffi_make_call_desc));
reg_fun(intern(lit("ffi-call"), user_package), func_n2v(ffi_call_wrap));
reg_fun(intern(lit("ffi-make-closure"), user_package), func_n4o(ffi_make_closure, 2));
+#endif
reg_fun(intern(lit("ffi-typedef"), user_package), func_n2(ffi_typedef));
reg_fun(intern(lit("ffi-size"), user_package), func_n1(ffi_size));
reg_fun(intern(lit("ffi-alignof"), user_package), func_n1(ffi_alignof));