diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-21 15:36:06 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-21 15:36:06 -0700 |
commit | b580e0f60eab4b23e782b0f2970823a51e5000bd (patch) | |
tree | 80511cf9d648084fb467aa9224421c90fb476558 /ffi.c | |
parent | 53fd7bd43eb9a513f5a81f9ebbd99a7cc4172430 (diff) | |
download | txr-b580e0f60eab4b23e782b0f2970823a51e5000bd.tar.gz txr-b580e0f60eab4b23e782b0f2970823a51e5000bd.tar.bz2 txr-b580e0f60eab4b23e782b0f2970823a51e5000bd.zip |
ffi: bugfix: revisit alignment.
Replace the incorrect alignment assumption for the basic types
(size == alignment) with the true calculation obtained from the
compiler.
* ffi.c (alignof): New macro.
(make_ffi_type_builtin): Take alignment as separate argument.
(ffi_type_compile, ffi_init_types): Using alignof macro,
calculate alignment of each type that is created using
make_ffi_type_builtin, and pass to that function.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 92 |
1 files changed, 62 insertions, 30 deletions
@@ -60,6 +60,8 @@ #define zalloca(size) memset(alloca(size), 0, size) +#define alignof(type) offsetof(struct {char x; type y;}, y) + val uint8_s, int8_s; val uint16_s, int16_s; val uint32_s, int32_s; @@ -1427,7 +1429,7 @@ static void ffi_carray_put(struct txr_ffi_type *tft, val carray, mem_t *dst, } static val make_ffi_type_builtin(val syntax, val lisp_type, - cnum size, ffi_type *ft, + cnum size, cnum align, ffi_type *ft, void (*put)(struct txr_ffi_type *, val obj, mem_t *dst, val self), val (*get)(struct txr_ffi_type *, @@ -1442,7 +1444,8 @@ static val make_ffi_type_builtin(val syntax, val lisp_type, tft->syntax = syntax; tft->lt = lisp_type; tft->mnames = tft->mtypes = nil; - tft->size = tft->align = size; + tft->size = size; + tft->align = align; tft->put = put; tft->get = get; tft->alloc = ffi_fixed_alloc; @@ -1746,6 +1749,7 @@ val ffi_type_compile(val syntax) cnum nelem = c_num(cadr(syntax)); val type = make_ffi_type_builtin(syntax, buf_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, if3(sym == buf_s, ffi_buf_put, ffi_buf_d_put), @@ -1769,6 +1773,7 @@ val ffi_type_compile(val syntax) } else if (sym == cptr_s) { val tag = cadr(syntax); val type = make_ffi_type_builtin(syntax, cptr_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, ffi_cptr_put, ffi_cptr_get); struct txr_ffi_type *tft = ffi_type_struct(type); @@ -1777,6 +1782,7 @@ val ffi_type_compile(val syntax) } else if (sym == carray_s) { val element_type = ffi_type_compile(cadr(syntax)); val type = make_ffi_type_builtin(syntax, carray_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, ffi_carray_put, ffi_carray_get); struct txr_ffi_type *tft = ffi_type_struct(type); @@ -1806,75 +1812,92 @@ static void ffi_init_types(void) #if HAVE_I8 ffi_typedef(uint8_s, make_ffi_type_builtin(uint8_s, integer_s, sizeof (i8_t), - &ffi_type_uint8, + alignof (i8_t), &ffi_type_uint8, ffi_u8_put, ffi_u8_get)); ffi_typedef(int8_s, make_ffi_type_builtin(int8_s, integer_s, sizeof (i8_t), - &ffi_type_sint8, + alignof (i8_t), &ffi_type_sint8, ffi_i8_put, ffi_i8_get)); #endif #if HAVE_I16 ffi_typedef(uint16_s, make_ffi_type_builtin(uint16_s, integer_s, - sizeof (i16_t), + sizeof (i16_t), alignof (i16_t), &ffi_type_uint16, ffi_u16_put, ffi_u16_get)); ffi_typedef(int16_s, make_ffi_type_builtin(int16_s, integer_s, - sizeof (i16_t), + sizeof (i16_t), alignof (i16_t), &ffi_type_sint16, ffi_i16_put, ffi_i16_get)); #endif #if HAVE_I32 ffi_typedef(uint32_s, make_ffi_type_builtin(uint32_s, integer_s, - sizeof (i32_t), &ffi_type_uint32, + sizeof (i32_t), alignof (i32_t), + &ffi_type_uint32, ffi_u32_put, ffi_u32_get)); ffi_typedef(int32_s, make_ffi_type_builtin(int32_s, integer_s, - sizeof (i32_t), &ffi_type_sint32, + sizeof (i32_t), alignof (i32_t), + &ffi_type_sint32, ffi_i32_put, ffi_i32_get)); #endif #if HAVE_I64 ffi_typedef(uint64_s, make_ffi_type_builtin(uint64_s, integer_s, - sizeof (i64_t), &ffi_type_uint64, + sizeof (i64_t), alignof (i64_t), + &ffi_type_uint64, ffi_u64_put, ffi_u64_get)); ffi_typedef(int64_s, make_ffi_type_builtin(int64_s, integer_s, - sizeof (i64_t), &ffi_type_sint64, + sizeof (i64_t), alignof (i64_t), + &ffi_type_sint64, ffi_i64_put, ffi_i64_get)); #endif - ffi_typedef(uchar_s, make_ffi_type_builtin(uchar_s, integer_s, 1, &ffi_type_uchar, + ffi_typedef(uchar_s, make_ffi_type_builtin(uchar_s, integer_s, 1, 1, + &ffi_type_uchar, ffi_uchar_put, ffi_uchar_get)); - ffi_typedef(char_s, make_ffi_type_builtin(char_s, integer_s, 1, + ffi_typedef(char_s, make_ffi_type_builtin(char_s, integer_s, 1, 1, ffi_char, ffi_char_put, ffi_char_get)); - ffi_typedef(bchar_s, make_ffi_type_builtin(bchar_s, char_s, - sizeof (char), &ffi_type_uchar, + ffi_typedef(bchar_s, make_ffi_type_builtin(bchar_s, char_s, 1, 1, + &ffi_type_uchar, ffi_uchar_put, ffi_bchar_get)); ffi_typedef(wchar_s, make_ffi_type_builtin(wchar_s, char_s, - sizeof (wchar_t), &ffi_type_wchar, + sizeof (wchar_t), + alignof (wchar_t), + &ffi_type_wchar, ffi_wchar_put, ffi_wchar_get)); ffi_typedef(ushort_s, make_ffi_type_builtin(ushort_s, integer_s, - sizeof (short), &ffi_type_ushort, + sizeof (short), alignof (short), + &ffi_type_ushort, ffi_ushort_put, ffi_ushort_get)); ffi_typedef(short_s, make_ffi_type_builtin(short_s, integer_s, - sizeof (short), &ffi_type_sshort, + sizeof (short), alignof (short), + &ffi_type_sshort, ffi_short_put, ffi_short_get)); ffi_typedef(int_s, make_ffi_type_builtin(int_s, integer_s, - sizeof (int), &ffi_type_sint, + sizeof (int), alignof (int), + &ffi_type_sint, ffi_int_put, ffi_int_get)); ffi_typedef(uint_s, make_ffi_type_builtin(uint_s, integer_s, - sizeof (int), &ffi_type_uint, + sizeof (int), alignof (int), + &ffi_type_uint, ffi_uint_put, ffi_uint_get)); ffi_typedef(ulong_s, make_ffi_type_builtin(ulong_s, integer_s, - sizeof (long), &ffi_type_ulong, + sizeof (long), alignof (long), + &ffi_type_ulong, ffi_ulong_put, ffi_ulong_get)); ffi_typedef(long_s, make_ffi_type_builtin(long_s, integer_s, - sizeof (long), &ffi_type_slong, + sizeof (long), alignof (long), + &ffi_type_slong, ffi_long_put, ffi_long_get)); ffi_typedef(float_s, make_ffi_type_builtin(float_s, float_s, - sizeof (float), &ffi_type_float, + sizeof (float), alignof (float), + &ffi_type_float, ffi_float_put, ffi_float_get)); ffi_typedef(double_s, make_ffi_type_builtin(double_s, float_s, - sizeof (double), &ffi_type_double, + sizeof (double), + alignof (double), + &ffi_type_double, ffi_double_put, ffi_double_get)); { val type = make_ffi_type_builtin(cptr_s, cptr_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, ffi_cptr_put, ffi_cptr_get); struct txr_ffi_type *tft = ffi_type_struct(type); @@ -1885,6 +1908,7 @@ static void ffi_init_types(void) { val type = make_ffi_type_builtin(str_s, str_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, ffi_str_put, ffi_str_get); struct txr_ffi_type *tft = ffi_type_struct(type); @@ -1895,6 +1919,7 @@ static void ffi_init_types(void) { val type = make_ffi_type_builtin(bstr_s, str_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, ffi_bstr_put, ffi_bstr_get); struct txr_ffi_type *tft = ffi_type_struct(type); @@ -1903,12 +1928,14 @@ static void ffi_init_types(void) ffi_typedef(bstr_s, type); } - ffi_typedef(str_d_s, make_ffi_type_builtin(str_d_s, str_s, - sizeof (mem_t *), &ffi_type_pointer, + ffi_typedef(str_d_s, make_ffi_type_builtin(str_d_s, str_s, sizeof (mem_t *), + alignof (mem_t *), + &ffi_type_pointer, ffi_str_put, ffi_str_d_get)); { val type = ffi_typedef(wstr_s, make_ffi_type_builtin(wstr_s, str_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, ffi_wstr_put, ffi_wstr_get)); @@ -1918,11 +1945,13 @@ static void ffi_init_types(void) ffi_typedef(wstr_s, type); } - ffi_typedef(wstr_d_s, make_ffi_type_builtin(wstr_d_s, str_s, - sizeof (mem_t *), &ffi_type_pointer, + ffi_typedef(wstr_d_s, make_ffi_type_builtin(wstr_d_s, str_s, sizeof (mem_t *), + alignof (mem_t *), + &ffi_type_pointer, ffi_wstr_put, ffi_wstr_d_get)); - ffi_typedef(bstr_d_s, make_ffi_type_builtin(bstr_d_s, str_s, - sizeof (mem_t *), &ffi_type_pointer, + ffi_typedef(bstr_d_s, make_ffi_type_builtin(bstr_d_s, str_s, sizeof (mem_t *), + alignof (mem_t *), + &ffi_type_pointer, ffi_bstr_put, ffi_bstr_d_get)); { @@ -1931,6 +1960,7 @@ static void ffi_init_types(void) for (iter = list(buf_s, buf_d_s, nao); iter; iter = cdr(iter)) { val sym = car(iter); ffi_typedef(sym, make_ffi_type_builtin(sym, buf_s, sizeof (mem_t *), + alignof (mem_t *), &ffi_type_pointer, if3(sym == buf_s, ffi_buf_put, ffi_buf_d_put), @@ -1940,9 +1970,11 @@ static void ffi_init_types(void) 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)); - ffi_typedef(void_s, make_ffi_type_builtin(void_s, null_s, 0, &ffi_type_void, + ffi_typedef(void_s, make_ffi_type_builtin(void_s, null_s, 0, 0, + &ffi_type_void, ffi_void_put, ffi_void_get)); } |