added more ffi module code
This commit is contained in:
parent
3841ce7445
commit
5b6347b0a9
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -24,7 +24,6 @@
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#include "mod-ffi.h"
|
||||
#include <hawk-utl.h>
|
||||
#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, "<ffi.close> %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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user