summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-02-15 07:29:31 +0000
committerKaz Kylheku <kaz@kylheku.com>2025-02-15 07:29:31 +0000
commit1de44cb970730cdf4f04ca91f9fc5e98fd411f63 (patch)
tree1cb04721f325258b0c744a62da9697164ec28a27
parentcc05029249b35b7f65e9a308a6d07aaed060c0b5 (diff)
downloadtxr-1de44cb970730cdf4f04ca91f9fc5e98fd411f63.tar.gz
txr-1de44cb970730cdf4f04ca91f9fc5e98fd411f63.tar.bz2
txr-1de44cb970730cdf4f04ca91f9fc5e98fd411f63.zip
ffi: rework endian-type rput/rget routines on big endian.
* ffi.c (ffi_be_i16_rput, ffi_be_i16_rget, ffi_be_u16_rput, ffi_be_u16_rget, ffi_be_i32_rput, ffi_be_i32_rget, ffi_be_u32_rput, ffi_be_u32_rget, ffi_le_i16_rput, ffi_le_i16_rget, ffi_le_u16_rput, ffi_le_u16_rget, ffi_le_i32_rput, ffi_le_i32_rget, ffi_le_u32_rput, ffi_le_u32_rget): Rewriten to avoid memory clearing, memsets, pointer arithmetic and use of helper functions. The big endian rput and rget functions just wrap the non-endian versions. The ones which need byte swapping work in terms of a full ffi_arg word. For instance to prepare a 16 bit big endian unsigned return value we byte swap the uin16_t, then convert fo ffi_arg.
-rw-r--r--ffi.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/ffi.c b/ffi.c
index 0aa019dc..aebd8234 100644
--- a/ffi.c
+++ b/ffi.c
@@ -2131,25 +2131,23 @@ static val ffi_wchar_rget(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_be_i16_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 6);
- ffi_be_i16_put(tft, n, dst + 6, self);
+ ffi_i16_rput(tft, n, dst, self);
}
static val ffi_be_i16_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_be_i16_get(tft, src + 6, self);
+ return ffi_i16_rget(tft, src, self);
}
static void ffi_be_u16_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 6);
- ffi_be_u16_put(tft, n, dst + 6, self);
+ ffi_u16_rput(tft, n, dst, self);
}
static val ffi_be_u16_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_be_u16_get(tft, src + 6, self);
+ return ffi_u16_rget(tft, src, self);
}
#endif
@@ -2159,25 +2157,23 @@ static val ffi_be_u16_rget(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_be_i32_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 4);
- ffi_be_i32_put(tft, n, dst + 4, self);
+ ffi_i32_rput(tft, n, dst, self);
}
static val ffi_be_i32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_be_i32_get(tft, src + 4, self);
+ return ffi_i32_rget(tft, src, self);
}
static void ffi_be_u32_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 4);
- ffi_be_u32_put(tft, n, dst + 4, self);
+ ffi_u32_rput(tft, n, dst, self);
}
static val ffi_be_u32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_be_u32_get(tft, src + 4, self);
+ return ffi_u32_rget(tft, src, self);
}
#endif
@@ -2187,25 +2183,35 @@ static val ffi_be_u32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_le_i16_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 6);
- ffi_le_i16_put(tft, n, dst + 6, self);
+ i16_t v = ffi_swap_i16(c_i16(n, self));
+ (void) tft;
+ (void) self;
+ *coerce(ffi_arg *, dst) = v;
}
static val ffi_le_i16_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_le_i16_get(tft, src + 6, self);
+ i16_t n = ffi_swap_i16(*coerce(ffi_arg *, src));
+ (void) tft;
+ (void) self;
+ return num_fast(n);
}
static void ffi_le_u16_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 6);
- ffi_le_u16_put(tft, n, dst + 6, self);
+ u16_t v = ffi_swap_u16(c_u16(n, self));
+ (void) tft;
+ (void) self;
+ *coerce(ffi_arg *, dst) = v;
}
static val ffi_le_u16_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_le_u16_get(tft, src + 6, self);
+ u16_t n = ffi_swap_u16(*coerce(ffi_arg *, src));
+ (void) tft;
+ (void) self;
+ return num_fast(n);
}
#endif
@@ -2215,25 +2221,35 @@ static val ffi_le_u16_rget(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_le_i32_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 4);
- ffi_le_i32_put(tft, n, dst + 4, self);
+ i32_t v = ffi_swap_i32(c_i32(n, self));
+ (void) tft;
+ (void) self;
+ *coerce(ffi_arg *, dst) = v;
}
static val ffi_le_i32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_le_i32_get(tft, src + 4, self);
+ i32_t n = ffi_swap_i32(*coerce(ffi_arg *, src));
+ (void) tft;
+ (void) self;
+ return num_fast(n);
}
static void ffi_le_u32_rput(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- memset(dst, 0, 4);
- ffi_le_u32_put(tft, n, dst + 4, self);
+ u32_t v = ffi_swap_u32(c_u32(n, self));
+ (void) tft;
+ (void) self;
+ *coerce(ffi_arg *, dst) = v;
}
static val ffi_le_u32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
{
- return ffi_le_u32_get(tft, src + 4, self);
+ u32_t n = ffi_swap_u32(*coerce(ffi_arg *, src));
+ (void) tft;
+ (void) self;
+ return num_fast(n);
}
#endif