summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-10-24 14:21:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-10-24 14:21:14 -0700
commit23ff8e0205eabea96a109efd249f82dd562cf74e (patch)
tree09ceab48c395b4fb4adc89337e5ac697700ac583 /ffi.c
parent84da351d88231cb480a25c816eff08d0669ac095 (diff)
downloadtxr-23ff8e0205eabea96a109efd249f82dd562cf74e.tar.gz
txr-23ff8e0205eabea96a109efd249f82dd562cf74e.tar.bz2
txr-23ff8e0205eabea96a109efd249f82dd562cf74e.zip
ffi: implement in-semantics for carray, cptr.
* ffi.c (ff_cptr_in, ffi_carray_in): New static functions. (ffi_type_compile): Wire in new functions for dynamically compiled cptr and carray types. (ffi_init_types): Also, wire in ffi_cptr_in function for the non-parametrized cptr type. (carray_set_ptr): New function. * ffi.h (carray_set_ptr): Declared. * txr.1: Documented.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c73
1 files changed, 68 insertions, 5 deletions
diff --git a/ffi.c b/ffi.c
index 2435bc8b..a383c831 100644
--- a/ffi.c
+++ b/ffi.c
@@ -1891,6 +1891,27 @@ static val ffi_cptr_get(struct txr_ffi_type *tft, mem_t *src, val self)
return cptr_typed(p, tft->tag, 0);
}
+static val ffi_cptr_in(struct txr_ffi_type *tft, int copy, mem_t *src,
+ val ptr, val self)
+{
+ if (ptr) {
+ if (copy) {
+ mem_t *newp = *coerce(mem_t **, src);
+
+ if (type(ptr) == CPTR) {
+ mem_t **addr = cptr_addr_of(ptr, tft->tag, self);
+ *addr = newp;
+ } else {
+ carray_set_ptr(ptr, tft->eltype, newp, self);
+ }
+ }
+ } else {
+ ptr = ffi_cptr_get(tft, src, self);
+ }
+
+ return ptr;
+}
+
static mem_t *ffi_cptr_alloc(struct txr_ffi_type *tft, val ptr, val self)
{
return coerce(mem_t *, cptr_addr_of(ptr, tft->tag, self));
@@ -2946,6 +2967,21 @@ static val ffi_carray_get(struct txr_ffi_type *tft, mem_t *src, val self)
return make_carray(tft->eltype, p, -1, nil, 0);
}
+static val ffi_carray_in(struct txr_ffi_type *tft, int copy, mem_t *src,
+ val carray, val self)
+{
+ if (carray) {
+ if (copy) {
+ mem_t *p = *coerce(mem_t **, src);
+ carray_set_ptr(carray, tft->eltype, p, self);
+ }
+ } else {
+ carray = ffi_carray_get(tft, src, self);
+ }
+
+ return carray;
+}
+
static void ffi_carray_put(struct txr_ffi_type *tft, val carray, mem_t *dst,
val self)
{
@@ -3945,6 +3981,7 @@ val ffi_type_compile(val syntax)
&ffi_type_pointer,
ffi_cptr_put, ffi_cptr_get, 0, 0);
struct txr_ffi_type *tft = ffi_type_struct(type);
+ tft->in = ffi_cptr_in;
tft->alloc = ffi_cptr_alloc;
tft->free = ffi_noop_free;
tft->tag = tag;
@@ -3953,12 +3990,17 @@ val ffi_type_compile(val syntax)
goto excess;
return type;
} else if (sym == carray_s) {
- val eltype = ffi_type_compile(cadr(syntax));
- if (cddr(syntax))
+ if (cddr(syntax)) {
goto excess;
- return make_ffi_type_pointer(syntax, carray_s,
- ffi_carray_put, ffi_carray_get,
- 0, 0, 0, eltype);
+ } else {
+ val eltype = ffi_type_compile(cadr(syntax));
+ val type = make_ffi_type_pointer(syntax, carray_s,
+ ffi_carray_put, ffi_carray_get,
+ 0, 0, 0, eltype);
+ struct txr_ffi_type *tft = ffi_type_struct(type);
+ tft->in = ffi_carray_in;
+ return type;
+ }
} else if (sym == sbit_s || sym == ubit_s) {
val nbits = ffi_eval_expr(cadr(syntax), nil, nil);
cnum nb = c_num(nbits, self);
@@ -4485,6 +4527,7 @@ static void ffi_init_types(void)
&ffi_type_pointer,
ffi_cptr_put, ffi_cptr_get, 0, 0);
struct txr_ffi_type *tft = ffi_type_struct(type);
+ tft->in = ffi_cptr_in;
tft->alloc = ffi_cptr_alloc;
tft->free = ffi_noop_free;
tft->tag = nil;
@@ -5430,6 +5473,26 @@ mem_t *carray_ptr(val carray, val type, val self)
return scry->data;
}
+void carray_set_ptr(val carray, val type, mem_t *ptr, val self)
+{
+ struct carray *scry = carray_struct_checked(self, carray);
+ if (scry->eltype != type)
+ uw_throwf(error_s, lit("~a: ~s is not of element type ~!~s"),
+ self, carray, type, nao);
+ if (carray->co.ops == &carray_borrowed_ops) {
+ /* nothing to do */
+ } else if (carray->co.ops == &carray_owned_ops) {
+ free(scry->data);
+ scry->nelem = 0;
+ carray->co.ops = &carray_borrowed_ops;
+ } else {
+ uw_throwf(error_s, lit("~a: cannot change address of mmapped ~!~s"),
+ self, carray, type, nao);
+ }
+
+ scry->data = ptr;
+}
+
val carray_vec(val vec, val type, val null_term_p)
{
val self = lit("carray-vec");