From 5b6347b0a9b50d3b47df2b1b24e4e06766c545c8 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 20 Dec 2020 17:50:30 +0000 Subject: [PATCH] added more ffi module code --- hawk/lib/parse.c | 3 + hawk/mod/Makefile.am | 6 +- hawk/mod/Makefile.in | 7 +- hawk/mod/mod-ffi.c | 453 +++++++++++++++++++++++++++++++++---------- hawk/mod/mod-ffi.h | 2 +- hawk/mod/mod-mysql.c | 1 + 6 files changed, 365 insertions(+), 107 deletions(-) diff --git a/hawk/lib/parse.c b/hawk/lib/parse.c index 6cdf6bea..3a913cbe 100644 --- a/hawk/lib/parse.c +++ b/hawk/lib/parse.c @@ -7409,6 +7409,9 @@ static struct int (*modload) (hawk_mod_t* mod, hawk_t* hawk); } static_modtab[] = { +#if defined(HAWK_ENABLE_MOD_FFI) + { HAWK_T("ffi"), hawk_mod_ffi }, +#endif { HAWK_T("hawk"), hawk_mod_hawk }, { HAWK_T("math"), hawk_mod_math }, #if defined(HAWK_ENABLE_MOD_MYSQL) diff --git a/hawk/mod/Makefile.am b/hawk/mod/Makefile.am index cd09a571..c91a3d89 100644 --- a/hawk/mod/Makefile.am +++ b/hawk/mod/Makefile.am @@ -68,10 +68,10 @@ endif #------------------------------------------------- if ENABLE_MOD_FFI libhawk_ffi_la_SOURCES = mod-ffi.c mod-ffi.h -libhawk_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON) $(MYSQL_CFLAGS) +libhawk_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON) libhawk_ffi_la_CFLAGS = $(CFLAGS_COMMON) -libhawk_ffi_la_LDFLAGS = $(LDFLAGS_COMMON) $(MYSQL_LDFLAGS) -libhawk_ffi_la_LIBADD = $(LIBADD_COMMON) $(MYSQL_LIBS) +libhawk_ffi_la_LDFLAGS = $(LDFLAGS_COMMON) +libhawk_ffi_la_LIBADD = $(LIBADD_COMMON) $(DYNCALL_LIBS) $(FFI_LIBS) endif if ENABLE_MOD_MYSQL diff --git a/hawk/mod/Makefile.in b/hawk/mod/Makefile.in index adee6eb9..df61b9ea 100644 --- a/hawk/mod/Makefile.in +++ b/hawk/mod/Makefile.in @@ -144,6 +144,7 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkgmodexec_LTLIBRARIES) am__DEPENDENCIES_1 = @ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_DEPENDENCIES = \ @ENABLE_MOD_FFI_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLE_MOD_FFI_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLE_MOD_FFI_TRUE@ $(am__DEPENDENCIES_1) am__libhawk_ffi_la_SOURCES_DIST = mod-ffi.c mod-ffi.h @ENABLE_MOD_FFI_TRUE@am_libhawk_ffi_la_OBJECTS = \ @@ -448,10 +449,10 @@ CFLAGS_COMMON = # ACTUAL MODULES #------------------------------------------------- @ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_SOURCES = mod-ffi.c mod-ffi.h -@ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON) $(MYSQL_CFLAGS) +@ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON) @ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_CFLAGS = $(CFLAGS_COMMON) -@ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_LDFLAGS = $(LDFLAGS_COMMON) $(MYSQL_LDFLAGS) -@ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_LIBADD = $(LIBADD_COMMON) $(MYSQL_LIBS) +@ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_LDFLAGS = $(LDFLAGS_COMMON) +@ENABLE_MOD_FFI_TRUE@libhawk_ffi_la_LIBADD = $(LIBADD_COMMON) $(DYNCALL_LIBS) $(FFI_LIBS) @ENABLE_MOD_MYSQL_TRUE@libhawk_mysql_la_SOURCES = mod-mysql.c mod-mysql.h @ENABLE_MOD_MYSQL_TRUE@libhawk_mysql_la_CPPFLAGS = $(CPPFLAGS_COMMON) $(MYSQL_CFLAGS) @ENABLE_MOD_MYSQL_TRUE@libhawk_mysql_la_CFLAGS = $(CFLAGS_COMMON) diff --git a/hawk/mod/mod-ffi.c b/hawk/mod/mod-ffi.c index 0e84ed43..58506295 100644 --- a/hawk/mod/mod-ffi.c +++ b/hawk/mod/mod-ffi.c @@ -24,7 +24,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if 0 #include "mod-ffi.h" #include #include "../lib/hawk-prv.h" @@ -74,8 +73,7 @@ #define __dcCallInt64 dcCallLongLong #endif - -#endif +#endif /* USE_DYNCALL */ #define FMTC_NULL '\0' /* internal use only */ @@ -118,7 +116,6 @@ union ffi_sv_t long long int ll; #endif - hawk_uint8_t ui8; hawk_int8_t i8; hawk_uint16_t ui16; @@ -156,7 +153,7 @@ struct ffi_t #define __IDMAP_NODE_T_DATA ffi_t ffi; -#define __IDMAP_LIST_T_DATA int errnum; hawk_ooch_t errmsg[256]; +#define __IDMAP_LIST_T_DATA hawk_ooch_t errmsg[256]; #define __IDMAP_LIST_T ffi_list_t #define __IDMAP_NODE_T ffi_node_t #define __INIT_IDMAP_LIST __init_ffi_list @@ -165,6 +162,82 @@ struct ffi_t #define __FREE_IDMAP_NODE __free_ffi_node #include "../lib/idmap-imp.h" +struct rtx_data_t +{ + ffi_list_t ffi_list; + +}; +typedef struct rtx_data_t rtx_data_t; + +/* ------------------------------------------------------------------------ */ +#define ERRNUM_TO_RC(errnum) (-((hawk_int_t)errnum)) + +static hawk_int_t copy_error_to_ffi_list (hawk_rtx_t* rtx, ffi_list_t* ffi_list) +{ + hawk_errnum_t errnum = hawk_rtx_geterrnum(rtx); + hawk_copy_oocstr (ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), hawk_rtx_geterrmsg(rtx)); + return ERRNUM_TO_RC(errnum); +} + +static hawk_int_t set_error_on_ffi_list_with_errno (hawk_rtx_t* rtx, ffi_list_t* ffi_list, const hawk_ooch_t* title) +{ + int err = errno; + + if (title) + hawk_rtx_fmttooocstr (rtx, ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), HAWK_T("%js - %hs"), title, strerror(err)); + else + hawk_rtx_fmttooocstr (rtx, ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), HAWK_T("%hs"), strerror(err)); + return ERRNUM_TO_RC(hawk_syserr_to_errnum(err)); +} + + +static hawk_int_t set_error_on_ffi_list (hawk_rtx_t* rtx, ffi_list_t* ffi_list, hawk_errnum_t errnum, const hawk_ooch_t* errfmt, ...) +{ + va_list ap; + if (errfmt) + { + va_start (ap, errfmt); + hawk_rtx_vfmttooocstr (rtx, ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), errfmt, ap); + va_end (ap); + } + else + { + hawk_rtx_fmttooocstr (rtx, ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), HAWK_T("%js"), hawk_geterrstr(hawk_rtx_gethawk(rtx))(errnum)); + } + return ERRNUM_TO_RC(errnum); +} + +static void set_errmsg_on_ffi_list (hawk_rtx_t* rtx, ffi_list_t* ffi_list, const hawk_ooch_t* errfmt, ...) +{ + if (errfmt) + { + va_list ap; + va_start (ap, errfmt); + hawk_rtx_vfmttooocstr (rtx, ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), errfmt, ap); + va_end (ap); + } + else + { + hawk_copy_oocstr (ffi_list->errmsg, HAWK_COUNTOF(ffi_list->errmsg), hawk_rtx_geterrmsg(rtx)); + } +} + +/* ------------------------------------------------------------------------ */ + +static HAWK_INLINE rtx_data_t* rtx_to_data (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + hawk_rbt_pair_t* pair; + pair = hawk_rbt_search((hawk_rbt_t*)fi->mod->ctx, &rtx, HAWK_SIZEOF(rtx)); + HAWK_ASSERT (pair != HAWK_NULL); + return (rtx_data_t*)HAWK_RBT_VPTR(pair); +} + +static HAWK_INLINE ffi_list_t* rtx_to_ffi_list (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + return &rtx_to_data(rtx, fi)->ffi_list; +} + +/* ------------------------------------------------------------------------ */ static HAWK_INLINE void link_ca (ffi_t* ffi, void* ptr) { @@ -173,137 +246,250 @@ static HAWK_INLINE void link_ca (ffi_t* ffi, void* ptr) ffi->ca = l; } -static void free_linked_cas (hawk_t* hawk, ffi_t* ffi) +static void free_linked_cas (hawk_rtx_t* rtx, ffi_t* ffi) { while (ffi->ca) { link_t* ptr; ptr = ffi->ca; ffi->ca = ptr->next; - hawk_freemem (hawk, ptr); + hawk_rtx_freemem (rtx, ptr); } } -static int fnc_open (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +/* ------------------------------------------------------------------------ */ + +static ffi_node_t* new_ffi_node (hawk_rtx_t* rtx, ffi_list_t* ffi_list, const hawk_ooch_t* name) { hawk_t* hawk = hawk_rtx_gethawk(rtx); - ffi_t* ffi; + ffi_node_t* ffi_node; hawk_mod_spec_t spec; void* handle; #if defined(USE_DYNCALL) DCCallVM* dc; #endif + ffi_node = __new_ffi_node(rtx, ffi_list); + if (!ffi_node) return HAWK_NULL; + + HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec)); + spec.name = name; + handle = hawk->prm.modopen(hawk, &spec); - if (!handle) goto softfail; + if (!handle) + { + const hawk_ooch_t* olderrmsg; + olderrmsg = hawk_backuperrmsg(hawk); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_ENOMEM, HAWK_T("unable to open the '%js' ffi module - %js"), name, olderrmsg); + + __free_ffi_node (rtx, ffi_list, ffi_node); + return HAWK_NULL; + } #if defined(USE_DYNCALL) dc = dcNewCallVM(4096); /* TODO: right size? */ if (!dc) { - hawk_seterrwithsyserr (hawk, 0, errno); - hawk->vmprim.dl_close (hawk, handle); - goto softfail; + hawk_rtx_seterrwithsyserr (hawk, 0, errno); + hawk->prm.modclose (hawk, handle); + __free_ffi_node (rtx, ffi_list, ffi_node); + return HAWK_NULL; } #endif - ffi->handle = handle; + ffi_node->ffi.handle = handle; #if defined(USE_DYNCALL) - ffi->dc = dc; + ffi_node->ffi.dc = dc; #elif defined(USE_LIBFFI) - ffi->fmtc_to_type[0][FMTC_NULL] = &ffi_type_void; - ffi->fmtc_to_type[1][FMTC_NULL] = &ffi_type_void; + ffi_node->ffi.fmtc_to_type[0][FMTC_NULL] = &ffi_type_void; + ffi_node->ffi.fmtc_to_type[1][FMTC_NULL] = &ffi_type_void; - ffi->fmtc_to_type[0][FMTC_CHAR] = &ffi_type_schar; - ffi->fmtc_to_type[1][FMTC_CHAR] = &ffi_type_uchar; - ffi->fmtc_to_type[0][FMTC_SHORT] = &ffi_type_sshort; - ffi->fmtc_to_type[1][FMTC_SHORT] = &ffi_type_ushort; - ffi->fmtc_to_type[0][FMTC_INT] = &ffi_type_sint; - ffi->fmtc_to_type[1][FMTC_INT] = &ffi_type_uint; - ffi->fmtc_to_type[0][FMTC_LONG] = &ffi_type_slong; - ffi->fmtc_to_type[1][FMTC_LONG] = &ffi_type_ulong; + ffi_node->ffi.fmtc_to_type[0][FMTC_CHAR] = &ffi_type_schar; + ffi_node->ffi.fmtc_to_type[1][FMTC_CHAR] = &ffi_type_uchar; + ffi_node->ffi.fmtc_to_type[0][FMTC_SHORT] = &ffi_type_sshort; + ffi_node->ffi.fmtc_to_type[1][FMTC_SHORT] = &ffi_type_ushort; + ffi_node->ffi.fmtc_to_type[0][FMTC_INT] = &ffi_type_sint; + ffi_node->ffi.fmtc_to_type[1][FMTC_INT] = &ffi_type_uint; + ffi_node->ffi.fmtc_to_type[0][FMTC_LONG] = &ffi_type_slong; + ffi_node->ffi.fmtc_to_type[1][FMTC_LONG] = &ffi_type_ulong; #if (HAWK_SIZEOF_LONG_LONG > 0) - ffi->fmtc_to_type[0][FMTC_LONGLONG] = &ffi_type_slonglong; - ffi->fmtc_to_type[1][FMTC_LONGLONG] = &ffi_type_ulonglong; + ffi_node->ffi.fmtc_to_type[0][FMTC_LONGLONG] = &ffi_type_slonglong; + ffi_node->ffi.fmtc_to_type[1][FMTC_LONGLONG] = &ffi_type_ulonglong; #endif - ffi->fmtc_to_type[0][FMTC_INT8] = &ffi_type_sint8; - ffi->fmtc_to_type[1][FMTC_INT8] = &ffi_type_uint8; - ffi->fmtc_to_type[0][FMTC_INT16] = &ffi_type_sint16; - ffi->fmtc_to_type[1][FMTC_INT16] = &ffi_type_uint16; - ffi->fmtc_to_type[0][FMTC_INT32] = &ffi_type_sint32; - ffi->fmtc_to_type[1][FMTC_INT32] = &ffi_type_uint32; - ffi->fmtc_to_type[0][FMTC_INT64] = &ffi_type_sint64; - ffi->fmtc_to_type[1][FMTC_INT64] = &ffi_type_uint64; + ffi_node->ffi.fmtc_to_type[0][FMTC_INT8] = &ffi_type_sint8; + ffi_node->ffi.fmtc_to_type[1][FMTC_INT8] = &ffi_type_uint8; + ffi_node->ffi.fmtc_to_type[0][FMTC_INT16] = &ffi_type_sint16; + ffi_node->ffi.fmtc_to_type[1][FMTC_INT16] = &ffi_type_uint16; + ffi_node->ffi.fmtc_to_type[0][FMTC_INT32] = &ffi_type_sint32; + ffi_node->ffi.fmtc_to_type[1][FMTC_INT32] = &ffi_type_uint32; + ffi_node->ffi.fmtc_to_type[0][FMTC_INT64] = &ffi_type_sint64; + ffi_node->ffi.fmtc_to_type[1][FMTC_INT64] = &ffi_type_uint64; - ffi->fmtc_to_type[0][FMTC_POINTER] = &ffi_type_pointer; - ffi->fmtc_to_type[1][FMTC_POINTER] = &ffi_type_pointer; - ffi->fmtc_to_type[0][FMTC_BCS] = &ffi_type_pointer; - ffi->fmtc_to_type[1][FMTC_BCS] = &ffi_type_pointer; - ffi->fmtc_to_type[0][FMTC_UCS] = &ffi_type_pointer; - ffi->fmtc_to_type[1][FMTC_UCS] = &ffi_type_pointer; + ffi_node->ffi.fmtc_to_type[0][FMTC_POINTER] = &ffi_type_pointer; + ffi_node->ffi.fmtc_to_type[1][FMTC_POINTER] = &ffi_type_pointer; + ffi_node->ffi.fmtc_to_type[0][FMTC_BCS] = &ffi_type_pointer; + ffi_node->ffi.fmtc_to_type[1][FMTC_BCS] = &ffi_type_pointer; + ffi_node->ffi.fmtc_to_type[0][FMTC_UCS] = &ffi_type_pointer; + ffi_node->ffi.fmtc_to_type[1][FMTC_UCS] = &ffi_type_pointer; #endif - HAWK_STACK_SETRETTORCV (hawk, nargs); - return HAWK_PF_SUCCESS; - -softfail: - HAWK_STACK_SETRETTOERRNUM (hawk, nargs); - return HAWK_PF_SUCCESS; + return ffi_node; } -static hawk_pfrc_t fnc_close (hawk_t* hawk, hawk_mod_t* mod, hawk_ooi_t nargs) +static void free_ffi_node (hawk_rtx_t* rtx, ffi_list_t* ffi_list, ffi_node_t* ffi_node) { - ffi_t* ffi; + hawk_t* hawk = hawk_rtx_gethawk(rtx); - HAWK_ASSERT (hawk, nargs == 0); - - ffi = (ffi_t*)hawk_getobjtrailer(hawk, HAWK_STACK_GETRCV(hawk, nargs), HAWK_NULL); - - if (!hawk->vmprim.dl_open) - { - hawk_seterrnum (hawk, HAWK_ENOIMPL); - goto softfail; - } - - HAWK_DEBUG1 (hawk, " %p\n", ffi->handle); - - free_linked_cas (hawk, ffi); + free_linked_cas (rtx, &ffi_node->ffi); #if defined(USE_DYNCALL) - dcFree (ffi->dc); - ffi->dc = HAWK_NULL; + dcFree (ffi_node->ffi.dc); + ffi_node->ffi.dc = HAWK_NULL; #elif defined(USE_LIBFFI) - if (ffi->arg_types) + if (ffi_node->ffi.arg_types) { - hawk_freemem (hawk, ffi->arg_types); - ffi->arg_types = HAWK_NULL; + hawk_rtx_freemem (rtx, ffi_node->ffi.arg_types); + ffi_node->ffi.arg_types = HAWK_NULL; } - if (ffi->arg_values) + if (ffi_node->ffi.arg_values) { - hawk_freemem (hawk, ffi->arg_values); - ffi->arg_values = HAWK_NULL; + hawk_rtx_freemem (rtx, ffi_node->ffi.arg_values); + ffi_node->ffi.arg_values = HAWK_NULL; } - if (ffi->arg_svs) + if (ffi_node->ffi.arg_svs) { - hawk_freemem (hawk, ffi->arg_svs); - ffi->arg_svs = HAWK_NULL; + hawk_rtx_freemem (rtx, ffi_node->ffi.arg_svs); + ffi_node->ffi.arg_svs = HAWK_NULL; } - ffi->arg_max = 0; - ffi->arg_count = 0; + ffi_node->ffi.arg_max = 0; + ffi_node->ffi.arg_count = 0; #endif - hawk->vmprim.dl_close (hawk, ffi->handle); - ffi->handle = HAWK_NULL; + hawk->prm.modclose (hawk, ffi_node->ffi.handle); + ffi_node->ffi.handle = HAWK_NULL; - HAWK_STACK_SETRETTORCV (hawk, nargs); - return HAWK_PF_SUCCESS; - -softfail: - HAWK_STACK_SETRETTOERRNUM (hawk, nargs); - return HAWK_PF_SUCCESS; + __free_ffi_node (rtx, ffi_list, ffi_node); } +static HAWK_INLINE ffi_node_t* get_ffi_list_node (ffi_list_t* ffi_list, hawk_int_t id) +{ + if (id < 0 || id >= ffi_list->map.high || !ffi_list->map.tab[id]) return HAWK_NULL; + return ffi_list->map.tab[id]; +} + +static ffi_node_t* get_ffi_list_node_with_arg (hawk_rtx_t* rtx, ffi_list_t* ffi_list, hawk_val_t* arg, hawk_int_t* rx) +{ + hawk_int_t id; + ffi_node_t* ffi_node; + + + if (hawk_rtx_valtoint(rtx, arg, &id) <= -1) + { + *rx = ERRNUM_TO_RC(hawk_rtx_geterrnum(rtx)); + set_errmsg_on_ffi_list (rtx, ffi_list, HAWK_T("illegal handle value")); + return HAWK_NULL; + } + else if (!(ffi_node = get_ffi_list_node(ffi_list, id))) + { + *rx = ERRNUM_TO_RC(HAWK_EINVAL); + set_errmsg_on_ffi_list (rtx, ffi_list, HAWK_T("invalid handle - %zd"), (hawk_oow_t)id); + return HAWK_NULL; + } + + return ffi_node; +} + +/* ------------------------------------------------------------------------ */ + +static int fnc_open (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + ffi_list_t* ffi_list; + ffi_node_t* ffi_node = HAWK_NULL; + hawk_int_t ret = -1; + hawk_val_t* retv; + hawk_val_t* a0; + hawk_oocs_t name; + + ffi_list = rtx_to_ffi_list(rtx, fi); + + a0 = hawk_rtx_getarg(rtx, 0); + name.ptr = hawk_rtx_getvaloocstr(rtx, a0, &name.len); + if (HAWK_UNLIKELY(!name.ptr)) + { + ret = copy_error_to_ffi_list (rtx, ffi_list); + goto done; + } + + if (name.len != hawk_count_oocstr(name.ptr)) + { + ret = set_error_on_ffi_list(rtx, ffi_list, HAWK_EINVAL, HAWK_T("invalid ffi module name '%.*js'"), name.len, name.ptr); + goto done; + } + + ffi_node = new_ffi_node(rtx, ffi_list, name.ptr); + if (ffi_node) ret = ffi_node->id; + else ret = copy_error_to_ffi_list (rtx, ffi_list); + +done: + if (name.ptr) hawk_rtx_freevaloocstr (rtx, a0, name.ptr); + + retv = hawk_rtx_makeintval(rtx, ret); + if (HAWK_UNLIKELY(!retv)) + { + if (ffi_node) free_ffi_node (rtx, ffi_list, ffi_node); + return -1; + } + + hawk_rtx_setretval (rtx, retv); + return 0; +} + +static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + hawk_t* hawk = hawk_rtx_gethawk(rtx); + ffi_list_t* ffi_list; + ffi_node_t* ffi_node; + hawk_int_t ret = -1; + + ffi_list = rtx_to_ffi_list(rtx, fi); + ffi_node = get_ffi_list_node_with_arg(rtx, ffi_list, hawk_rtx_getarg(rtx, 0), &ret); + if (ffi_node) + { + free_linked_cas (rtx, &ffi_node->ffi); + + #if defined(USE_DYNCALL) + dcFree (ffi_node->ffi.dc); + ffi_node->ffi.dc = HAWK_NULL; + #elif defined(USE_LIBFFI) + if (ffi_node->ffi.arg_types) + { + hawk_rtx_freemem (rtx, ffi_node->ffi.arg_types); + ffi_node->ffi.arg_types = HAWK_NULL; + } + if (ffi_node->ffi.arg_values) + { + hawk_rtx_freemem (rtx, ffi_node->ffi.arg_values); + ffi_node->ffi.arg_values = HAWK_NULL; + } + if (ffi_node->ffi.arg_svs) + { + hawk_rtx_freemem (rtx, ffi_node->ffi.arg_svs); + ffi_node->ffi.arg_svs = HAWK_NULL; + } + ffi_node->ffi.arg_max = 0; + ffi_node->ffi.arg_count = 0; + #endif + + hawk->prm.modclose (hawk, ffi_node->ffi.handle); + ffi_node->ffi.handle = HAWK_NULL; + } + + hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ret)); + return 0; +} + +#if 0 static HAWK_INLINE int add_ffi_arg (hawk_t* hawk, ffi_t* ffi, hawk_ooch_t fmtc, int _unsigned, hawk_oop_t arg) { #if defined(USE_LIBFFI) @@ -317,11 +503,11 @@ static HAWK_INLINE int add_ffi_arg (hawk_t* hawk, ffi_t* ffi, hawk_ooch_t fmtc, newmax = ffi->arg_max + 16; /* TODO: adjust this? */ ttmp = hawk_reallocmem(hawk, ffi->arg_types, HAWK_SIZEOF(*ttmp) * newmax); - if (!ttmp) goto oops; + if (HAWK_UNLIKELY(!ttmp)) goto oops; vtmp = hawk_reallocmem(hawk, ffi->arg_values, HAWK_SIZEOF(*vtmp) * newmax); - if (!vtmp) goto oops; + if (HAWK_UNLIKELY(!vtmp)) goto oops; stmp = hawk_reallocmem(hawk, ffi->arg_svs, HAWK_SIZEOF(*stmp) * newmax); - if (!stmp) goto oops; + if (HAWK_UNLIKELY(!stmp)) goto oops; ffi->arg_types = ttmp; ffi->arg_values = vtmp; @@ -1185,15 +1371,30 @@ softfail: HAWK_STACK_SETRETTOERRNUM (hawk, nargs); return HAWK_PF_SUCCESS; } +#endif +static int fnc_errmsg (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) +{ + ffi_list_t* ffi_list; + hawk_val_t* retv; + + ffi_list = rtx_to_ffi_list(rtx, fi); + retv = hawk_rtx_makestrvalwithoocstr(rtx, ffi_list->errmsg); + if (!retv) return -1; + + hawk_rtx_setretval (rtx, retv); + return 0; +} /* ------------------------------------------------------------------------ */ static hawk_mod_fnc_tab_t fnctab[] = { - { HAWK_T("call"), { { 3, 3, HAWK_NULL }, fnc_call, 0 } }, - { HAWK_T("close"), { { 0, 0, HAWK_NULL }, fnc_close, 0 } }, - { HAWK_T("getsym"), { { 1, 1, HAWK_NULL }, fnc_getsym, 0 } }, - { HAWK_T("open"), { { 1, 1, HAWK_NULL }, fnc_open, 0 } } + //{ HAWK_T("call"), { { 3, 3, HAWK_NULL }, fnc_call, 0 } }, + { HAWK_T("close"), { { 1, 1, HAWK_NULL }, fnc_close, 0 } }, + { HAWK_T("errmsg"), { { 0, 0, HAWK_NULL }, fnc_errmsg, 0 } }, + //{ HAWK_T("getsym"), { { 1, 1, HAWK_NULL }, fnc_getsym, 0 } }, + { HAWK_T("open"), { { 1, 1, HAWK_NULL }, fnc_open, 0 } } + }; /* ------------------------------------------------------------------------ */ @@ -1203,17 +1404,69 @@ static int query (hawk_mod_t* mod, hawk_t* hawk, const hawk_ooch_t* name, hawk_m return hawk_findmodsymfnc(hawk, fnctab, HAWK_COUNTOF(fnctab), name, sym); } -static void unload (hawk_t* hawk, hawk_mod_t* mod) +static int init (hawk_mod_t* mod, hawk_rtx_t* rtx) { - /* TODO: anything? close open open dll handles? For that, fnc_open must store the value it returns to mod->ctx or somewhere..*/ - /* TODO: track all opened shared objects... clear all external memories/resources created but not cleared (for lacking the call to 'close') */ -} + hawk_rbt_t* rbt; + rtx_data_t data, * datap; + hawk_rbt_pair_t* pair; + + rbt = (hawk_rbt_t*)mod->ctx; + + HAWK_MEMSET (&data, 0, HAWK_SIZEOF(data)); + pair = hawk_rbt_insert(rbt, &rtx, HAWK_SIZEOF(rtx), &data, HAWK_SIZEOF(data)); + if (HAWK_UNLIKELY(!pair)) return -1; + + datap = (rtx_data_t*)HAWK_RBT_VPTR(pair); + __init_ffi_list (rtx, &datap->ffi_list); + + return 0; +} + +static void fini (hawk_mod_t* mod, hawk_rtx_t* rtx) +{ + hawk_rbt_t* rbt; + hawk_rbt_pair_t* pair; + + rbt = (hawk_rbt_t*)mod->ctx; + + /* garbage clean-up */ + pair = hawk_rbt_search(rbt, &rtx, HAWK_SIZEOF(rtx)); + if (pair) + { + rtx_data_t* data; + + data = (rtx_data_t*)HAWK_RBT_VPTR(pair); + + __fini_ffi_list (rtx, &data->ffi_list); + + hawk_rbt_delete (rbt, &rtx, HAWK_SIZEOF(rtx)); + } +} + +static void unload (hawk_mod_t* mod, hawk_t* hawk) +{ + hawk_rbt_t* rbt; + + rbt = (hawk_rbt_t*)mod->ctx; + + HAWK_ASSERT (HAWK_RBT_SIZE(rbt) == 0); + hawk_rbt_close (rbt); +} + +int hawk_mod_ffi (hawk_mod_t* mod, hawk_t* hawk) +{ + hawk_rbt_t* rbt; + + mod->query = query; + mod->unload = unload; + mod->init = init; + mod->fini = fini; + + rbt = hawk_rbt_open(hawk_getgem(hawk), 0, 1, 1); + if (HAWK_UNLIKELY(!rbt)) return -1; + + hawk_rbt_setstyle (rbt, hawk_get_rbt_style(HAWK_RBT_STYLE_INLINE_COPIERS)); + mod->ctx = rbt; -int hawk_mod_ffi (hawk_t* hawk, hawk_mod_t* mod) -{ - mod->query = query; - mod->unload = unload; - mod->ctx = HAWK_NULL; return 0; } -#endif diff --git a/hawk/mod/mod-ffi.h b/hawk/mod/mod-ffi.h index 0410abee..53b834eb 100644 --- a/hawk/mod/mod-ffi.h +++ b/hawk/mod/mod-ffi.h @@ -33,7 +33,7 @@ extern "C" { #endif -HAWK_EXPORT int hawk_mod_ffi (hawk_t* hawk, hawk_mod_t* mod); +HAWK_EXPORT int hawk_mod_ffi (hawk_mod_t* mod, hawk_t* hawk); #if defined(__cplusplus) } diff --git a/hawk/mod/mod-mysql.c b/hawk/mod/mod-mysql.c index 35d6320e..cccb2ee8 100644 --- a/hawk/mod/mod-mysql.c +++ b/hawk/mod/mod-mysql.c @@ -115,6 +115,7 @@ static sql_node_t* new_sql_node (hawk_rtx_t* rtx, sql_list_t* sql_list) sql_node->mysql = mysql_init(HAWK_NULL); if (!sql_node->mysql) { + __free_sql_node (rtx, sql_list, sql_node); hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_ENOMEM, HAWK_T("unable to allocate a mysql object")); return HAWK_NULL; }