summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-03 06:09:23 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-03 06:09:23 -0700
commit244d706de560cad057d2853c2736a3008b0d8004 (patch)
treeca9641e9ac03fd62d9a74d911d551dddd2c87e62 /ffi.c
parent5f8e2b6572241951c5b264707a05af76e3e9cda9 (diff)
downloadtxr-244d706de560cad057d2853c2736a3008b0d8004.tar.gz
txr-244d706de560cad057d2853c2736a3008b0d8004.tar.bz2
txr-244d706de560cad057d2853c2736a3008b0d8004.zip
ffi: instantiate simple types just once.
* ffi.c (ffi_type_compile): All cases where the syntax is an atom just go through the ffi_typedef_hash lookup to retrieve a single type instance. (ffi_init_types): New function. Populates typedefs using construction code that was previously in ffi_type_compile. (ffi_init): Call ffi_init_types.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c242
1 files changed, 119 insertions, 123 deletions
diff --git a/ffi.c b/ffi.c
index fe18b23f..8fab53d9 100644
--- a/ffi.c
+++ b/ffi.c
@@ -1319,148 +1319,143 @@ val ffi_type_compile(val syntax)
uw_throwf(error_s, lit("~a: unrecognized type operator: ~s"),
self, sym, nao);
+ } else {
+ val sub = gethash(ffi_typedef_hash, syntax);
+
+ if (sub != nil)
+ return sub;
+
+ uw_throwf(error_s, lit("~a: unrecognized type specifier: ~!~s"),
+ self, syntax, nao);
+ }
+}
+
+static void ffi_init_types(void)
+{
+#if UCHAR_MAX == CHAR_MAX
+ ffi_type *ffi_char = &ffi_type_uchar;
+#else
+ ffi_type *ffi_char = &ffi_type_schar;
+#endif
+
#if HAVE_I8
- } else if (syntax == uint8_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i8_t),
- &ffi_type_uint8,
- ffi_u8_put, ffi_u8_get);
-
- } else if (syntax == int8_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i8_t),
- &ffi_type_sint8,
- ffi_i8_put, ffi_i8_get);
+ ffi_typedef(uint8_s, make_ffi_type_builtin(uint8_s, integer_s, sizeof (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,
+ ffi_i8_put, ffi_i8_get));
#endif
#if HAVE_I16
- } else if (syntax == uint16_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i16_t),
- &ffi_type_uint16,
- ffi_u16_put, ffi_u16_get);
- } else if (syntax == int16_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i16_t),
- &ffi_type_sint16,
- ffi_i16_put, ffi_i16_get);
+ ffi_typedef(uint16_s, make_ffi_type_builtin(uint16_s, integer_s,
+ sizeof (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),
+ &ffi_type_sint16,
+ ffi_i16_put, ffi_i16_get));
#endif
#if HAVE_I32
- } else if (syntax == uint32_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i32_t),
- &ffi_type_uint32,
- ffi_u32_put, ffi_u32_get);
- } else if (syntax == int32_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i32_t),
- &ffi_type_sint32,
- ffi_i32_put, ffi_i32_get);
+ ffi_typedef(uint32_s, make_ffi_type_builtin(uint32_s, integer_s,
+ sizeof (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,
+ ffi_i32_put, ffi_i32_get));
#endif
#if HAVE_I64
- } else if (syntax == uint64_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i64_t),
- &ffi_type_uint64,
- ffi_u64_put, ffi_u64_get);
- } else if (syntax == int64_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (i64_t),
- &ffi_type_sint64,
- ffi_i64_put, ffi_i64_get);
+ ffi_typedef(uint64_s, make_ffi_type_builtin(uint64_s, integer_s,
+ sizeof (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,
+ ffi_i64_put, ffi_i64_get));
#endif
- } else if (syntax == uchar_s) {
- return make_ffi_type_builtin(syntax, integer_s, 1, &ffi_type_uchar,
- ffi_uchar_put, ffi_uchar_get);
- } else if (syntax == char_s) {
-#if UCHAR_MAX == CHAR_MAX
- ffi_type *ffi_char = &ffi_type_uchar;
-#else
- ffi_type *ffi_char = &ffi_type_schar;
-#endif
- return make_ffi_type_builtin(syntax, integer_s, 1, ffi_char,
- ffi_char_put, ffi_char_get);
- } else if (syntax == wchar_s) {
- return make_ffi_type_builtin(syntax, char_s, sizeof (wchar_t),
- &ffi_type_wchar,
- ffi_wchar_put, ffi_wchar_get);
- } else if (syntax == ushort_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (short),
- &ffi_type_ushort,
- ffi_ushort_put, ffi_ushort_get);
- } else if (syntax == short_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (short),
- &ffi_type_sshort,
- ffi_short_put, ffi_short_get);
- } else if (syntax == int_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (int),
- &ffi_type_sint,
- ffi_int_put, ffi_int_get);
- } else if (syntax == uint_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (int),
- &ffi_type_uint,
- ffi_uint_put, ffi_uint_get);
- } else if (syntax == ulong_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (long),
- &ffi_type_ulong,
- ffi_ulong_put, ffi_ulong_get);
- } else if (syntax == long_s) {
- return make_ffi_type_builtin(syntax, integer_s, sizeof (long),
- &ffi_type_slong,
- ffi_long_put, ffi_long_get);
- } else if (syntax == float_s) {
- return make_ffi_type_builtin(syntax, float_s, sizeof (float),
- &ffi_type_float,
- ffi_float_put, ffi_float_get);
- } else if (syntax == double_s) {
- return make_ffi_type_builtin(syntax, float_s, sizeof (double),
- &ffi_type_double,
- ffi_double_put, ffi_double_get);
- } else if (syntax == cptr_s) {
- val type = make_ffi_type_builtin(syntax, cptr_s, sizeof (mem_t *),
+ ffi_typedef(uchar_s, make_ffi_type_builtin(uchar_s, integer_s, 1, &ffi_type_uchar,
+ ffi_uchar_put, ffi_uchar_get));
+ ffi_typedef(char_s, make_ffi_type_builtin(char_s, integer_s, 1,
+ ffi_char, ffi_char_put, ffi_char_get));
+ ffi_typedef(wchar_s, make_ffi_type_builtin(wchar_s, char_s,
+ sizeof (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,
+ ffi_ushort_put, ffi_ushort_get));
+ ffi_typedef(short_s, make_ffi_type_builtin(short_s, integer_s,
+ sizeof (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,
+ ffi_int_put, ffi_int_get));
+ ffi_typedef(uint_s, make_ffi_type_builtin(uint_s, integer_s,
+ sizeof (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,
+ ffi_ulong_put, ffi_ulong_get));
+ ffi_typedef(long_s, make_ffi_type_builtin(long_s, integer_s,
+ sizeof (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,
+ ffi_float_put, ffi_float_get));
+ ffi_typedef(double_s, make_ffi_type_builtin(double_s, float_s,
+ sizeof (double), &ffi_type_double,
+ ffi_double_put, ffi_double_get));
+
+ {
+ val type = make_ffi_type_builtin(cptr_s, cptr_s, sizeof (mem_t *),
&ffi_type_pointer,
ffi_cptr_put, ffi_cptr_get);
struct txr_ffi_type *tft = ffi_type_struct(type);
tft->alloc = ffi_cptr_alloc;
tft->free = ffi_noop_free;
- return type;
- } else if (syntax == str_s) {
- val type = make_ffi_type_builtin(syntax, str_s, sizeof (mem_t *),
+ ffi_typedef(cptr_s, type);
+ }
+
+ {
+ val type = make_ffi_type_builtin(str_s, str_s, sizeof (mem_t *),
&ffi_type_pointer,
ffi_str_put, ffi_str_get);
struct txr_ffi_type *tft = ffi_type_struct(type);
tft->in = ffi_freeing_in;
- return type;
- } else if (syntax == str_d_s) {
- val type = make_ffi_type_builtin(syntax, str_s, sizeof (mem_t *),
- &ffi_type_pointer,
- ffi_str_d_put, ffi_str_d_get);
- return type;
- } else if (syntax == wstr_s) {
- return make_ffi_type_builtin(syntax, str_s, sizeof (mem_t *),
- &ffi_type_pointer,
- ffi_wstr_put, ffi_wstr_get);
- } else if (syntax == wstr_d_s) {
- return make_ffi_type_builtin(syntax, str_s, sizeof (mem_t *),
- &ffi_type_pointer,
- ffi_wstr_d_put, ffi_wstr_d_get);
- } else if (syntax == buf_s || syntax == buf_d_s) {
- val type = make_ffi_type_builtin(syntax, buf_s, sizeof (mem_t *),
- &ffi_type_pointer,
- if3(syntax == buf_s,
- ffi_buf_put, ffi_buf_d_put),
- ffi_void_get);
- struct txr_ffi_type *tft = ffi_type_struct(type);
- tft->alloc = ffi_buf_alloc;
- tft->free = ffi_noop_free;
- return type;
- } else if (syntax == closure_s) {
- return make_ffi_type_builtin(syntax, fun_s, sizeof (mem_t *),
- &ffi_type_pointer,
- ffi_closure_put, ffi_cptr_get);
- } else if (syntax == void_s) {
- return make_ffi_type_builtin(syntax, null_s, 0, &ffi_type_void,
- ffi_void_put, ffi_void_get);
- } else {
- val sub = gethash(ffi_typedef_hash, syntax);
-
- if (sub != nil)
- return sub;
+ ffi_typedef(str_s, type);
+ }
- uw_throwf(error_s, lit("~a: unrecognized type specifier: ~!~s"),
- self, syntax, nao);
+ ffi_typedef(str_d_s, make_ffi_type_builtin(str_d_s, str_s,
+ sizeof (mem_t *), &ffi_type_pointer,
+ ffi_str_d_put, ffi_str_d_get));
+ ffi_typedef(wstr_s, make_ffi_type_builtin(wstr_s, str_s,
+ sizeof (mem_t *), &ffi_type_pointer,
+ ffi_wstr_put, ffi_wstr_get));
+ ffi_typedef(wstr_d_s, make_ffi_type_builtin(wstr_d_s, str_s,
+ sizeof (mem_t *), &ffi_type_pointer,
+ ffi_wstr_d_put, ffi_wstr_d_get));
+
+ {
+ val iter;
+
+ for (iter = list(buf_s, buf_d_s, nao); iter; iter = cdr(iter)) {
+ val sym = car(iter);
+ val type = make_ffi_type_builtin(sym, buf_s, sizeof (mem_t *),
+ &ffi_type_pointer,
+ if3(sym == buf_s,
+ ffi_buf_put, ffi_buf_d_put),
+ ffi_void_get);
+ struct txr_ffi_type *tft = ffi_type_struct(type);
+ tft->alloc = ffi_buf_alloc;
+ tft->free = ffi_noop_free;
+ ffi_typedef(sym, type);
+ }
}
+
+ ffi_typedef(closure_s, make_ffi_type_builtin(closure_s, fun_s,
+ sizeof (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_void_put, ffi_void_get));
}
struct txr_ffi_call_desc {
@@ -1722,4 +1717,5 @@ void ffi_init(void)
reg_fun(intern(lit("ffi-typedef"), user_package), func_n2(ffi_typedef));
reg_varl(intern(lit("cptr-null"), user_package), cptr(0));
ffi_typedef_hash = make_hash(nil, nil, nil);
+ ffi_init_types();
}