From 65f2f862f8282f8d940d592d51ba21569d30c2e0 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Mon, 9 Jan 2017 13:41:11 +0000 Subject: [PATCH] started taking ffi out of the main vm, putting it to a separate module --- moo/kernel/FFI.moo | 69 ++++++++++ moo/kernel/Moo.moo | 73 +--------- moo/lib/Makefile.am | 4 +- moo/lib/Makefile.in | 4 +- moo/lib/exec.c | 295 +-------------------------------------- moo/mod/Makefile.am | 27 ++-- moo/mod/Makefile.in | 83 ++++++----- moo/mod/_ffi.h | 43 ++++++ moo/mod/ffi.c | 326 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 505 insertions(+), 419 deletions(-) create mode 100644 moo/kernel/FFI.moo create mode 100644 moo/mod/_ffi.h create mode 100644 moo/mod/ffi.c diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo new file mode 100644 index 0000000..b435af6 --- /dev/null +++ b/moo/kernel/FFI.moo @@ -0,0 +1,69 @@ +class FFI(Object) +{ + dcl name handle funcs. + + method(#class) new: aString + { + ^self new open: aString. + } + + method open: aString + { + self.funcs := Dictionary new. + self.name := aString. + + self.handle := self privateOpen: self.name. + + "[ self.handle := self privateOpen: self.name ] + on: Exception do: [ + ] + on: XException do: [ + ]." + + ^self. + } + + method close + { + self privateClose: self.handle. + self.handle := nil. + } + + method call: aFunctionName withSig: aString withArgs: anArray + { + | f | + + ## f := self.funcs at: aFunctionName. + ## f isNil ifTrue: [ + ## f := self privateGetSymbol: aFunctionName in: self.handle. + ## f isNil ifTrue: [ self error: 'No such function' ]. + ## self.funcs at: aFunctionName put: f. + ## ]. +f := self privateGetSymbol: aFunctionName in: self.handle. +f isNil ifTrue: [ self error: 'No such function' ]. + + ^self privateCall: f withSig: aString withArgs: anArray + } + + method privateOpen: aString + { + + ^nil. ## TODO: Error signal: 'can not open' + } + + method privateClose: aHandle + { + + } + + method privateCall: aSymbol withSig: aString withArgs: anArray + { + + } + + method privateGetSymbol: aString in: aHandle + { + + ^nil. + } +} diff --git a/moo/kernel/Moo.moo b/moo/kernel/Moo.moo index 244adc0..6d20017 100644 --- a/moo/kernel/Moo.moo +++ b/moo/kernel/Moo.moo @@ -9,77 +9,6 @@ (* -------------------------------------------------------------------------- *) -class FFI(Object) -{ - dcl name handle funcs. - - method(#class) new: aString - { - ^self new open: aString. - } - - method open: aString - { - self.funcs := Dictionary new. - self.name := aString. - - self.handle := self privateOpen: self.name. - - "[ self.handle := self privateOpen: self.name ] - on: Exception do: [ - ] - on: XException do: [ - ]." - - ^self. - } - - method close - { - self privateClose: self.handle. - self.handle := nil. - } - - method call: aFunctionName withSig: aString withArgs: anArray - { - | f | - - ## f := self.funcs at: aFunctionName. - ## f isNil ifTrue: [ - ## f := self privateGetSymbol: aFunctionName in: self.handle. - ## f isNil ifTrue: [ self error: 'No such function' ]. - ## self.funcs at: aFunctionName put: f. - ## ]. -f := self privateGetSymbol: aFunctionName in: self.handle. -f isNil ifTrue: [ self error: 'No such function' ]. - - ^self privateCall: f withSig: aString withArgs: anArray - } - - method privateOpen: aString - { - - ^nil. ## TODO: Error signal: 'can not open' - } - - method privateClose: aHandle - { - - } - - method privateCall: aSymbol withSig: aString withArgs: anArray - { - - } - - method privateGetSymbol: aString in: aHandle - { - - ^nil. - } -} - -(* -------------------------------------------------------------------------- *) - +(*#include 'FFI.moo'.*) #include 'Stdio.moo'. #include 'Console.moo'. diff --git a/moo/lib/Makefile.am b/moo/lib/Makefile.am index 7d000dd..e95df6b 100644 --- a/moo/lib/Makefile.am +++ b/moo/lib/Makefile.am @@ -60,14 +60,14 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON) if ENABLE_STATIC_MODULE libmoo_la_LDFLAGS += -L$(abs_builddir)/../mod -libmoo_la_LIBADD += -lmoo-console -lmoo-stdio -ltermcap +libmoo_la_LIBADD += -lmoo-console -lmoo-stdio #-ltermcap endif bin_PROGRAMS = moo moo_SOURCES = main.c moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) moo_LDFLAGS = $(LDFLAGS_LIB_COMMON) -moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo #-ldyncall_s +moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo install-data-hook: diff --git a/moo/lib/Makefile.in b/moo/lib/Makefile.in index df74e61..b633007 100644 --- a/moo/lib/Makefile.in +++ b/moo/lib/Makefile.in @@ -84,7 +84,7 @@ host_triplet = @host@ @WIN32_TRUE@am__append_1 = -DMOO_DEFAULT_MODPREFIX=\"libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"-1\" @WIN32_FALSE@am__append_2 = -DMOO_DEFAULT_MODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"\" @ENABLE_STATIC_MODULE_TRUE@am__append_3 = -L$(abs_builddir)/../mod -@ENABLE_STATIC_MODULE_TRUE@am__append_4 = -lmoo-console -lmoo-stdio -ltermcap +@ENABLE_STATIC_MODULE_TRUE@am__append_4 = -lmoo-console -lmoo-stdio #-ltermcap bin_PROGRAMS = moo$(EXEEXT) subdir = lib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ @@ -430,7 +430,7 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_4) moo_SOURCES = main.c moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) moo_LDFLAGS = $(LDFLAGS_LIB_COMMON) -moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo #-ldyncall_s +moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo all: moo-cfg.h $(MAKE) $(AM_MAKEFLAGS) all-am diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 23de083..31807ec 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -50,11 +50,6 @@ # endif #endif -#if defined(USE_DYNCALL) -/* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ -# include /* TODO: remove this. make dyXXXX calls to callbacks */ -#endif - #define PROC_STATE_RUNNING 3 #define PROC_STATE_WAITING 2 @@ -76,7 +71,6 @@ (MOO_OOP_TO_SMOOI((x)->heap_ftime_sec) == MOO_OOP_TO_SMOOI((y)->heap_ftime_sec) && MOO_OOP_TO_SMOOI((x)->heap_ftime_nsec) < MOO_OOP_TO_SMOOI((y)->heap_ftime_nsec)) \ ) - #define LOAD_IP(moo, v_ctx) ((moo)->ip = MOO_OOP_TO_SMOOI((v_ctx)->ip)) #define STORE_IP(moo, v_ctx) ((v_ctx)->ip = MOO_SMOOI_TO_OOP((moo)->ip)) @@ -2658,287 +2652,6 @@ static moo_pfrc_t pf_error_as_string (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_ffi_open (moo_t* moo, moo_ooi_t nargs) -{ - moo_oop_t rcv, arg; - void* handle; - - MOO_ASSERT (moo, nargs == 1); - - rcv = MOO_STACK_GETRCV(moo, nargs); - arg = MOO_STACK_GETARG(moo, nargs, 0); - - if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR)) - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - if (!moo->vmprim.dl_open) - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - -/* TODO: check null-termination... */ - handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)arg)->slot); - if (!handle) - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - MOO_STACK_POP (moo); -/* TODO: how to hold an address? as an integer???? or a byte array? fix this not to loose accuracy*/ - MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(handle)); - - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_ffi_close (moo_t* moo, moo_ooi_t nargs) -{ - moo_oop_t rcv, arg; - void* handle; - - MOO_ASSERT (moo, nargs == 1); - - rcv = MOO_STACK_GETRCV(moo, nargs); - arg = MOO_STACK_GETARG(moo, nargs, 0); - - - if (!MOO_OOP_IS_SMOOI(arg)) - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - MOO_STACK_POP (moo); - - handle = (void*)MOO_OOP_TO_SMOOI(arg); /* TODO: how to store void* ???. fix this not to loose accuracy */ - if (moo->vmprim.dl_close) moo->vmprim.dl_close (moo, handle); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_ffi_call (moo_t* moo, moo_ooi_t nargs) -{ -#if defined(USE_DYNCALL) - moo_oop_t rcv, fun, sig, args; - - MOO_ASSERT (moo, nargs == 3); - - rcv = MOO_STACK_GET(moo, moo->sp - 3); - fun = MOO_STACK_GET(moo, moo->sp - 2); - sig = MOO_STACK_GET(moo, moo->sp - 1); - args = MOO_STACK_GET(moo, moo->sp); - - if (!MOO_OOP_IS_SMOOI(fun)) /* TODO: how to store pointer */ - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0) - { -MOO_DEBUG0 (moo, "FFI: wrong signature...\n"); - return MOO_PF_FAILURE; - } - - if (MOO_CLASSOF(moo,args) != moo->_array) /* TODO: check if arr is a kind of array??? or check if it's indexed */ - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - { - moo_oow_t i; - DCCallVM* dc; - void* f; - moo_oop_oop_t arr; - int mode_set; - - f = MOO_OOP_TO_SMOOI(fun); /* TODO: decode pointer properly */ - arr = (moo_oop_oop_t)args; - - dc = dcNewCallVM (4096); - if (!dc) return MOO_PF_HARD_FAILURE; /* TODO: proper error handling */ - -MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f); - /*dcMode (dc, DC_CALL_C_DEFAULT); - dcReset (dc);*/ - - /*for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++) - { - if (((moo_oop_char_t)sig)->slot[i] == '|') - { - dcMode (dc, DC_CALL_C_ELLIPSIS); -MOO_DEBUG0 (moo, "CALL MODE 111 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); - mode_set = 1; - break; - } - } - if (!mode_set) */ dcMode (dc, DC_CALL_C_DEFAULT); - - for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++) - { -MOO_DEBUG1 (moo, "FFI: CALLING ARG %c\n", ((moo_oop_char_t)sig)->slot[i]); - switch (((moo_oop_char_t)sig)->slot[i]) - { - /* TODO: support more types... */ - /* - case '|': - dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS); -MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); - break; - */ - - case 'c': - /* TODO: sanity check on the argument type */ - dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 2])); - break; - - case 'i': - dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); - break; - - case 'l': - dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); - break; - - case 'L': - dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); - break; - - case 's': - { - moo_oow_t bcslen, ucslen; - moo_bch_t bcs[1024]; - - ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 2]); - moo_convootobchars (moo, ((moo_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */ - - bcs[bcslen] = '\0'; - dcArgPointer (dc, bcs); - break; - } - - default: - /* TODO: ERROR HANDLING */ - break; - } - - } - - MOO_STACK_POPS (moo, nargs); - - switch (((moo_oop_char_t)sig)->slot[0]) - { -/* TODO: support more types... */ -/* TODO: proper return value conversion */ - case 'c': - { - char r = dcCallChar (dc, f); - MOO_STACK_SETTOP (moo, MOO_CHAR_TO_OOP(r)); - break; - } - - case 'i': - { - int r = dcCallInt (dc, f); -MOO_DEBUG1 (moo, "CALLED... %d\n", r); -MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); - MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); - break; - } - - case 'l': - { - long r = dcCallLong (dc, f); - MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); - break; - } - - case 'L': - { - long long r = dcCallLongLong (dc, f); - MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); - break; - } - - case 's': - { - moo_oow_t bcslen, ucslen; - moo_ooch_t ucs[1024]; - moo_oop_t s; - char* r = dcCallPointer (dc, f); - - bcslen = strlen(r); - moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* proper string conversion */ - - s = moo_makestring(moo, ucs, ucslen) - if (!s) - { - dcFree (dc); - return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */ - } - - MOO_STACK_SETTOP (moo, s); - break; - } - - default: - /* TOOD: ERROR HANDLING */ - break; - } - - dcFree (dc); - } - - return MOO_PF_SUCCESS; -#else - return MOO_PF_FAILURE; -#endif -} - -static moo_pfrc_t pf_ffi_getsym (moo_t* moo, moo_ooi_t nargs) -{ - moo_oop_t rcv, hnd, fun; - void* sym; - - MOO_ASSERT (moo, nargs == 2); - - rcv = MOO_STACK_GET(moo, moo->sp - 2); - fun = MOO_STACK_GET(moo, moo->sp - 1); - hnd = MOO_STACK_GET(moo, moo->sp); - - if (!MOO_OOP_IS_SMOOI(hnd)) /* TODO: how to store pointer */ - { - /* TODO: more info on error */ - return MOO_PF_FAILURE; - } - - if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR)) - { -MOO_DEBUG0 (moo, "wrong function name...\n"); - return MOO_PF_FAILURE; - } - - if (!moo->vmprim.dl_getsym) - { - return MOO_PF_FAILURE; - } - - sym = moo->vmprim.dl_getsym (moo, (void*)MOO_OOP_TO_SMOOI(hnd), ((moo_oop_char_t)fun)->slot); - if (!sym) - { - return MOO_PF_FAILURE; - } - -/* TODO: how to hold an address? as an integer???? or a byte array? */ - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(sym)); - - return MOO_PF_SUCCESS; -} #define MAX_NARGS MOO_TYPE_MAX(moo_ooi_t) struct pf_t @@ -3019,13 +2732,7 @@ static pf_t pftab[] = { 0, 0, pf_error_as_character, "_error_as_character" }, { 0, 0, pf_error_as_integer, "_error_as_integer" }, - { 0, 0, pf_error_as_string, "_error_as_string" }, - - { 1, 1, pf_ffi_open, "_ffi_open" }, - { 1, 1, pf_ffi_close, "_ffi_close" }, - { 2, 2, pf_ffi_getsym, "_ffi_getsym" }, - { 3, 3, pf_ffi_call, "_ffi_call" } - + { 0, 0, pf_error_as_string, "_error_as_string" } }; int moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len) diff --git a/moo/mod/Makefile.am b/moo/mod/Makefile.am index 32d3263..d730154 100644 --- a/moo/mod/Makefile.am +++ b/moo/mod/Makefile.am @@ -20,14 +20,10 @@ if ENABLE_STATIC_MODULE ################################################## # STATIC MODULES BUILT INTO MAIN LIBRARY ################################################## +LDFLAGS_COMMON = +LIBADD_COMMON = -noinst_LTLIBRARIES = libmoo-console.la libmoo-stdio.la - -libmoo_console_la_SOURCES = console.c -libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON) - -libmoo_stdio_la_SOURCES = stdio.c -libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) +noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la else @@ -38,19 +34,22 @@ LDFLAGS_COMMON = -L$(abs_builddir)/../lib -L$(libdir) -version-info 1:0:0 -no-un LIBADD_COMMON = -lmoo pkgmodexecdir = $(libdir) +pkgmodexec_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la -pkgmodexec_LTLIBRARIES = libmoo-stdio.la libmoo-console.la - -libmoo_stdio_la_SOURCES = stdio.c _stdio.h -libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) -libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON) -libmoo_stdio_la_LIBADD = $(LIBADD_COMMON) +endif libmoo_console_la_SOURCES = console.c console.h libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON) libmoo_console_la_LDFLAGS = $(LDFLAGS_COMMON) libmoo_console_la_LIBADD = $(LIBADD_COMMON) -ltermcap -endif +libmoo_ffi_la_SOURCES = ffi.c _ffi.h +libmoo_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON) +libmoo_ffi_la_LDFLAGS = $(LDFLAGS_COMMON) +libmoo_ffi_la_LIBADD = $(LIBADD_COMMON) -ldyncall_s +libmoo_stdio_la_SOURCES = stdio.c _stdio.h +libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) +libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON) +libmoo_stdio_la_LIBADD = $(LIBADD_COMMON) diff --git a/moo/mod/Makefile.in b/moo/mod/Makefile.in index 7338ea7..f047098 100644 --- a/moo/mod/Makefile.in +++ b/moo/mod/Makefile.in @@ -129,13 +129,8 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pkgmodexecdir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkgmodexec_LTLIBRARIES) am__DEPENDENCIES_1 = -@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_DEPENDENCIES = \ -@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1) -am__libmoo_console_la_SOURCES_DIST = console.c console.h -@ENABLE_STATIC_MODULE_FALSE@am_libmoo_console_la_OBJECTS = \ -@ENABLE_STATIC_MODULE_FALSE@ libmoo_console_la-console.lo -@ENABLE_STATIC_MODULE_TRUE@am_libmoo_console_la_OBJECTS = \ -@ENABLE_STATIC_MODULE_TRUE@ libmoo_console_la-console.lo +libmoo_console_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libmoo_console_la_OBJECTS = libmoo_console_la-console.lo libmoo_console_la_OBJECTS = $(am_libmoo_console_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -148,13 +143,17 @@ libmoo_console_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @ENABLE_STATIC_MODULE_FALSE@am_libmoo_console_la_rpath = -rpath \ @ENABLE_STATIC_MODULE_FALSE@ $(pkgmodexecdir) @ENABLE_STATIC_MODULE_TRUE@am_libmoo_console_la_rpath = -@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_DEPENDENCIES = \ -@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1) -am__libmoo_stdio_la_SOURCES_DIST = stdio.c _stdio.h -@ENABLE_STATIC_MODULE_FALSE@am_libmoo_stdio_la_OBJECTS = \ -@ENABLE_STATIC_MODULE_FALSE@ libmoo_stdio_la-stdio.lo -@ENABLE_STATIC_MODULE_TRUE@am_libmoo_stdio_la_OBJECTS = \ -@ENABLE_STATIC_MODULE_TRUE@ libmoo_stdio_la-stdio.lo +libmoo_ffi_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libmoo_ffi_la_OBJECTS = libmoo_ffi_la-ffi.lo +libmoo_ffi_la_OBJECTS = $(am_libmoo_ffi_la_OBJECTS) +libmoo_ffi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libmoo_ffi_la_LDFLAGS) $(LDFLAGS) -o $@ +@ENABLE_STATIC_MODULE_FALSE@am_libmoo_ffi_la_rpath = -rpath \ +@ENABLE_STATIC_MODULE_FALSE@ $(pkgmodexecdir) +@ENABLE_STATIC_MODULE_TRUE@am_libmoo_ffi_la_rpath = +libmoo_stdio_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libmoo_stdio_la_OBJECTS = libmoo_stdio_la-stdio.lo libmoo_stdio_la_OBJECTS = $(am_libmoo_stdio_la_OBJECTS) libmoo_stdio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -197,9 +196,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libmoo_console_la_SOURCES) $(libmoo_stdio_la_SOURCES) -DIST_SOURCES = $(am__libmoo_console_la_SOURCES_DIST) \ - $(am__libmoo_stdio_la_SOURCES_DIST) +SOURCES = $(libmoo_console_la_SOURCES) $(libmoo_ffi_la_SOURCES) \ + $(libmoo_stdio_la_SOURCES) +DIST_SOURCES = $(libmoo_console_la_SOURCES) $(libmoo_ffi_la_SOURCES) \ + $(libmoo_stdio_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -389,30 +389,32 @@ CPPFLAGS_COMMON = -I$(abs_builddir) -I$(abs_builddir)/../lib \ -I$(abs_srcdir) -I$(abs_srcdir)/../lib -I$(includedir) -fPIC \ $(am__append_1) $(am__append_2) -################################################## -# STATIC MODULES BUILT INTO MAIN LIBRARY -################################################## -@ENABLE_STATIC_MODULE_TRUE@noinst_LTLIBRARIES = libmoo-console.la libmoo-stdio.la -@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_SOURCES = console.c console.h -@ENABLE_STATIC_MODULE_TRUE@libmoo_console_la_SOURCES = console.c -@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON) -@ENABLE_STATIC_MODULE_TRUE@libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON) -@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_SOURCES = stdio.c _stdio.h -@ENABLE_STATIC_MODULE_TRUE@libmoo_stdio_la_SOURCES = stdio.c -@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) -@ENABLE_STATIC_MODULE_TRUE@libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) - ################################################## # DYNAMIC MODULES ################################################## @ENABLE_STATIC_MODULE_FALSE@LDFLAGS_COMMON = -L$(abs_builddir)/../lib -L$(libdir) -version-info 1:0:0 -no-undefined + +################################################## +# STATIC MODULES BUILT INTO MAIN LIBRARY +################################################## +@ENABLE_STATIC_MODULE_TRUE@LDFLAGS_COMMON = @ENABLE_STATIC_MODULE_FALSE@LIBADD_COMMON = -lmoo +@ENABLE_STATIC_MODULE_TRUE@LIBADD_COMMON = +@ENABLE_STATIC_MODULE_TRUE@noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la @ENABLE_STATIC_MODULE_FALSE@pkgmodexecdir = $(libdir) -@ENABLE_STATIC_MODULE_FALSE@pkgmodexec_LTLIBRARIES = libmoo-stdio.la libmoo-console.la -@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON) -@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_LIBADD = $(LIBADD_COMMON) -@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_LDFLAGS = $(LDFLAGS_COMMON) -@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_LIBADD = $(LIBADD_COMMON) -ltermcap +@ENABLE_STATIC_MODULE_FALSE@pkgmodexec_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la +libmoo_console_la_SOURCES = console.c console.h +libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON) +libmoo_console_la_LDFLAGS = $(LDFLAGS_COMMON) +libmoo_console_la_LIBADD = $(LIBADD_COMMON) -ltermcap +libmoo_ffi_la_SOURCES = ffi.c _ffi.h +libmoo_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON) +libmoo_ffi_la_LDFLAGS = $(LDFLAGS_COMMON) +libmoo_ffi_la_LIBADD = $(LIBADD_COMMON) -ldyncall_s +libmoo_stdio_la_SOURCES = stdio.c _stdio.h +libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON) +libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON) +libmoo_stdio_la_LIBADD = $(LIBADD_COMMON) all: all-am .SUFFIXES: @@ -497,6 +499,9 @@ clean-pkgmodexecLTLIBRARIES: libmoo-console.la: $(libmoo_console_la_OBJECTS) $(libmoo_console_la_DEPENDENCIES) $(EXTRA_libmoo_console_la_DEPENDENCIES) $(AM_V_CCLD)$(libmoo_console_la_LINK) $(am_libmoo_console_la_rpath) $(libmoo_console_la_OBJECTS) $(libmoo_console_la_LIBADD) $(LIBS) +libmoo-ffi.la: $(libmoo_ffi_la_OBJECTS) $(libmoo_ffi_la_DEPENDENCIES) $(EXTRA_libmoo_ffi_la_DEPENDENCIES) + $(AM_V_CCLD)$(libmoo_ffi_la_LINK) $(am_libmoo_ffi_la_rpath) $(libmoo_ffi_la_OBJECTS) $(libmoo_ffi_la_LIBADD) $(LIBS) + libmoo-stdio.la: $(libmoo_stdio_la_OBJECTS) $(libmoo_stdio_la_DEPENDENCIES) $(EXTRA_libmoo_stdio_la_DEPENDENCIES) $(AM_V_CCLD)$(libmoo_stdio_la_LINK) $(am_libmoo_stdio_la_rpath) $(libmoo_stdio_la_OBJECTS) $(libmoo_stdio_la_LIBADD) $(LIBS) @@ -507,6 +512,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_console_la-console.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_ffi_la-ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_stdio_la-stdio.Plo@am__quote@ .c.o: @@ -540,6 +546,13 @@ libmoo_console_la-console.lo: console.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_console_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_console_la-console.lo `test -f 'console.c' || echo '$(srcdir)/'`console.c +libmoo_ffi_la-ffi.lo: ffi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_ffi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_ffi_la-ffi.lo -MD -MP -MF $(DEPDIR)/libmoo_ffi_la-ffi.Tpo -c -o libmoo_ffi_la-ffi.lo `test -f 'ffi.c' || echo '$(srcdir)/'`ffi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_ffi_la-ffi.Tpo $(DEPDIR)/libmoo_ffi_la-ffi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ffi.c' object='libmoo_ffi_la-ffi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_ffi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_ffi_la-ffi.lo `test -f 'ffi.c' || echo '$(srcdir)/'`ffi.c + libmoo_stdio_la-stdio.lo: stdio.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_stdio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_stdio_la-stdio.lo -MD -MP -MF $(DEPDIR)/libmoo_stdio_la-stdio.Tpo -c -o libmoo_stdio_la-stdio.lo `test -f 'stdio.c' || echo '$(srcdir)/'`stdio.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_stdio_la-stdio.Tpo $(DEPDIR)/libmoo_stdio_la-stdio.Plo diff --git a/moo/mod/_ffi.h b/moo/mod/_ffi.h new file mode 100644 index 0000000..edee49b --- /dev/null +++ b/moo/mod/_ffi.h @@ -0,0 +1,43 @@ +/* + * $Id$ + * + Copyright (c) 2006-2016 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MOO_LIB_MOD_FFI_H_ +#define _MOO_LIB_MOD_FFI_H_ + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +MOO_EXPORT int moo_mod_ffi (moo_t* moo, moo_mod_t* mod); + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c new file mode 100644 index 0000000..2eb5c06 --- /dev/null +++ b/moo/mod/ffi.c @@ -0,0 +1,326 @@ +/* + * $Id$ + * + Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if 0 + +#include "_ffi.h" +#include + +#if defined(USE_DYNCALL) +/* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ +# include /* TODO: remove this. make dyXXXX calls to callbacks */ +#endif + + + { 1, 1, pf_ffi_open, "_ffi_open" }, + { 1, 1, pf_ffi_close, "_ffi_close" }, + { 2, 2, pf_ffi_getsym, "_ffi_getsym" }, + { 3, 3, pf_ffi_call, "_ffi_call" } + + + +static moo_pfrc_t pf_ffi_open (moo_t* moo, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg; + void* handle; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR)) + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + if (!moo->vmprim.dl_open) + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + +/* TODO: check null-termination... */ + handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)arg)->slot); + if (!handle) + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + MOO_STACK_POP (moo); +/* TODO: how to hold an address? as an integer???? or a byte array? fix this not to loose accuracy*/ + MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(handle)); + + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_ffi_close (moo_t* moo, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg; + void* handle; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + + if (!MOO_OOP_IS_SMOOI(arg)) + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + MOO_STACK_POP (moo); + + handle = (void*)MOO_OOP_TO_SMOOI(arg); /* TODO: how to store void* ???. fix this not to loose accuracy */ + if (moo->vmprim.dl_close) moo->vmprim.dl_close (moo, handle); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_ffi_call (moo_t* moo, moo_ooi_t nargs) +{ +#if defined(USE_DYNCALL) + moo_oop_t rcv, fun, sig, args; + + MOO_ASSERT (moo, nargs == 3); + + rcv = MOO_STACK_GET(moo, moo->sp - 3); + fun = MOO_STACK_GET(moo, moo->sp - 2); + sig = MOO_STACK_GET(moo, moo->sp - 1); + args = MOO_STACK_GET(moo, moo->sp); + + if (!MOO_OOP_IS_SMOOI(fun)) /* TODO: how to store pointer */ + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0) + { +MOO_DEBUG0 (moo, "FFI: wrong signature...\n"); + return MOO_PF_FAILURE; + } + + if (MOO_CLASSOF(moo,args) != moo->_array) /* TODO: check if arr is a kind of array??? or check if it's indexed */ + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + { + moo_oow_t i; + DCCallVM* dc; + void* f; + moo_oop_oop_t arr; + int mode_set; + + f = MOO_OOP_TO_SMOOI(fun); /* TODO: decode pointer properly */ + arr = (moo_oop_oop_t)args; + + dc = dcNewCallVM (4096); + if (!dc) return MOO_PF_HARD_FAILURE; /* TODO: proper error handling */ + +MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f); + /*dcMode (dc, DC_CALL_C_DEFAULT); + dcReset (dc);*/ + + /*for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++) + { + if (((moo_oop_char_t)sig)->slot[i] == '|') + { + dcMode (dc, DC_CALL_C_ELLIPSIS); +MOO_DEBUG0 (moo, "CALL MODE 111 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); + mode_set = 1; + break; + } + } + if (!mode_set) */ dcMode (dc, DC_CALL_C_DEFAULT); + + for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++) + { +MOO_DEBUG1 (moo, "FFI: CALLING ARG %c\n", ((moo_oop_char_t)sig)->slot[i]); + switch (((moo_oop_char_t)sig)->slot[i]) + { + /* TODO: support more types... */ + /* + case '|': + dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS); +MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); + break; + */ + + case 'c': + /* TODO: sanity check on the argument type */ + dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 2])); + break; + + case 'i': + dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); + break; + + case 'l': + dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); + break; + + case 'L': + dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); + break; + + case 's': + { + moo_oow_t bcslen, ucslen; + moo_bch_t bcs[1024]; + + ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 2]); + moo_convootobchars (moo, ((moo_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */ + + bcs[bcslen] = '\0'; + dcArgPointer (dc, bcs); + break; + } + + default: + /* TODO: ERROR HANDLING */ + break; + } + + } + + MOO_STACK_POPS (moo, nargs); + + switch (((moo_oop_char_t)sig)->slot[0]) + { +/* TODO: support more types... */ +/* TODO: proper return value conversion */ + case 'c': + { + char r = dcCallChar (dc, f); + MOO_STACK_SETTOP (moo, MOO_CHAR_TO_OOP(r)); + break; + } + + case 'i': + { + int r = dcCallInt (dc, f); +MOO_DEBUG1 (moo, "CALLED... %d\n", r); +MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); + MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); + break; + } + + case 'l': + { + long r = dcCallLong (dc, f); + MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); + break; + } + + case 'L': + { + long long r = dcCallLongLong (dc, f); + MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); + break; + } + + case 's': + { + moo_oow_t bcslen, ucslen; + moo_ooch_t ucs[1024]; + moo_oop_t s; + char* r = dcCallPointer (dc, f); + + bcslen = strlen(r); + moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* proper string conversion */ + + s = moo_makestring(moo, ucs, ucslen) + if (!s) + { + dcFree (dc); + return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */ + } + + MOO_STACK_SETTOP (moo, s); + break; + } + + default: + /* TOOD: ERROR HANDLING */ + break; + } + + dcFree (dc); + } + + return MOO_PF_SUCCESS; +#else + return MOO_PF_FAILURE; +#endif +} + +static moo_pfrc_t pf_ffi_getsym (moo_t* moo, moo_ooi_t nargs) +{ + moo_oop_t rcv, hnd, fun; + void* sym; + + MOO_ASSERT (moo, nargs == 2); + + rcv = MOO_STACK_GET(moo, moo->sp - 2); + fun = MOO_STACK_GET(moo, moo->sp - 1); + hnd = MOO_STACK_GET(moo, moo->sp); + + if (!MOO_OOP_IS_SMOOI(hnd)) /* TODO: how to store pointer */ + { + /* TODO: more info on error */ + return MOO_PF_FAILURE; + } + + if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR)) + { +MOO_DEBUG0 (moo, "wrong function name...\n"); + return MOO_PF_FAILURE; + } + + if (!moo->vmprim.dl_getsym) + { + return MOO_PF_FAILURE; + } + + sym = moo->vmprim.dl_getsym (moo, (void*)MOO_OOP_TO_SMOOI(hnd), ((moo_oop_char_t)fun)->slot); + if (!sym) + { + return MOO_PF_FAILURE; + } + +/* TODO: how to hold an address? as an integer???? or a byte array? */ + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(sym)); + + return MOO_PF_SUCCESS; +} +#endif