summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-29 12:26:26 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-29 12:26:26 -0700
commit5c9f482790a97c075d75d903e35a4cf7f09134c2 (patch)
tree9c8e4b88126049f024c1d8ea7564bd58b6805cf6
parentcced80ab687b521a1d07e53e1be70a33ea711d0f (diff)
downloadtxr-5c9f482790a97c075d75d903e35a4cf7f09134c2.tar.gz
txr-5c9f482790a97c075d75d903e35a4cf7f09134c2.tar.bz2
txr-5c9f482790a97c075d75d903e35a4cf7f09134c2.zip
ffi: ptr types map between nil and null pointers.
On the way out, if a ptr or ptr-in type encounters nil, it passes a null pointer. On the way in, a null C pointer received by a ptr type turns to the nil object. * ffi.c (ffi_ptr_in_put, ffi_ptr_in_d_put, ffi_ptr_out_put, ffi_ptr_put): Check for nil, and put out null pointer in that case. (ffi_ptr_out_get, ffi_ptr_out_d_get): Check for null pointer coming in and turn to nil.
-rw-r--r--ffi.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/ffi.c b/ffi.c
index c1be817b..103e79eb 100644
--- a/ffi.c
+++ b/ffi.c
@@ -716,9 +716,13 @@ static void ffi_ptr_in_put(struct txr_ffi_type *tft, val s, mem_t *dst,
val tgttype = tft->mtypes;
struct txr_ffi_type *tgtft = ffi_type_struct(tgttype);
mem_t *buf = tgtft->alloc(tgtft, s, self);
- tgtft->put(tgtft, s, buf, rtvec, self);
- rtvec[tft->rtidx] = buf;
- *coerce(mem_t **, dst) = buf;
+ if (s == nil) {
+ *coerce(mem_t **, dst) = rtvec[tft->rtidx] = 0;
+ } else {
+ tgtft->put(tgtft, s, buf, rtvec, self);
+ rtvec[tft->rtidx] = buf;
+ *coerce(mem_t **, dst) = buf;
+ }
}
static void ffi_ptr_in_d_put(struct txr_ffi_type *tft, val s, mem_t *dst,
@@ -726,10 +730,15 @@ static void ffi_ptr_in_d_put(struct txr_ffi_type *tft, val s, mem_t *dst,
{
val tgttype = tft->mtypes;
struct txr_ffi_type *tgtft = ffi_type_struct(tgttype);
- mem_t *buf = tgtft->alloc(tgtft, s, self);
- (void) rtvec;
- tgtft->put(tgtft, s, buf, rtvec, self);
- *coerce(mem_t **, dst) = buf;
+
+ if (s == nil) {
+ *coerce(mem_t **, dst) = 0;
+ } else {
+ mem_t *buf = tgtft->alloc(tgtft, s, self);
+ (void) rtvec;
+ tgtft->put(tgtft, s, buf, rtvec, self);
+ *coerce(mem_t **, dst) = buf;
+ }
}
static void ffi_ptr_out_in(struct txr_ffi_type *tft, val obj,
@@ -749,9 +758,13 @@ static void ffi_ptr_out_put(struct txr_ffi_type *tft, val s, mem_t *dst,
{
val tgttype = tft->mtypes;
struct txr_ffi_type *tgtft = ffi_type_struct(tgttype);
- mem_t *buf = tgtft->alloc(tgtft, s, self);
- rtvec[tft->rtidx] = buf;
- *coerce(mem_t **, dst) = buf;
+ if (s == nil) {
+ *coerce(mem_t **, dst) = rtvec[tft->rtidx] = 0;
+ } else {
+ mem_t *buf = tgtft->alloc(tgtft, s, self);
+ rtvec[tft->rtidx] = buf;
+ *coerce(mem_t **, dst) = buf;
+ }
}
static val ffi_ptr_out_get(struct txr_ffi_type *tft, mem_t *src, val self)
@@ -759,7 +772,7 @@ static val ffi_ptr_out_get(struct txr_ffi_type *tft, mem_t *src, val self)
val tgttype = tft->mtypes;
struct txr_ffi_type *tgtft = ffi_type_struct(tgttype);
mem_t *ptr = *coerce(mem_t **, src);
- return tgtft->get(tgtft, ptr, self);
+ return ptr ? tgtft->get(tgtft, ptr, self) : nil;
}
static val ffi_ptr_out_d_get(struct txr_ffi_type *tft, mem_t *src, val self)
@@ -767,7 +780,7 @@ static val ffi_ptr_out_d_get(struct txr_ffi_type *tft, mem_t *src, val self)
val tgttype = tft->mtypes;
struct txr_ffi_type *tgtft = ffi_type_struct(tgttype);
mem_t *ptr = *coerce(mem_t **, src);
- val ret = tgtft->get(tgtft, ptr, self);
+ val ret = ptr ? tgtft->get(tgtft, ptr, self) : nil;
free(ptr);
return ret;
}
@@ -777,10 +790,14 @@ static void ffi_ptr_put(struct txr_ffi_type *tft, val s, mem_t *dst,
{
val tgttype = tft->mtypes;
struct txr_ffi_type *tgtft = ffi_type_struct(tgttype);
- mem_t *buf = tgtft->alloc(tgtft, s, self);
- tgtft->put(tgtft, s, buf, rtvec, self);
- rtvec[tft->rtidx] = buf;
- *coerce(mem_t **, dst) = buf;
+ if (s == nil) {
+ *coerce(mem_t **, dst) = 0;
+ } else {
+ mem_t *buf = tgtft->alloc(tgtft, s, self);
+ tgtft->put(tgtft, s, buf, rtvec, self);
+ rtvec[tft->rtidx] = buf;
+ *coerce(mem_t **, dst) = buf;
+ }
}
static void ffi_struct_walk(struct txr_ffi_type *tft, mem_t *ctx,