From faf6ca28e5a24e76560ed609258f9406d102277b Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 10 Jan 2017 10:50:26 +0000 Subject: [PATCH] added MOO_VMPRIM_OPENDL_PFMOD. started refactoring ffi handling code --- moo/kernel/FFI.moo | 69 ++++------ moo/kernel/Mill.moo | 10 +- moo/kernel/Module.moo | 18 +++ moo/kernel/Moo.moo | 3 +- moo/kernel/Stdio.moo | 14 +- moo/lib/Makefile.am | 2 +- moo/lib/Makefile.in | 2 +- moo/lib/icc.mak | 38 ++++++ moo/lib/main.c | 85 +++++++----- moo/lib/moo-prv.h | 15 +-- moo/lib/moo.c | 6 +- moo/lib/moo.h | 27 +++- moo/mod/Makefile.am | 8 +- moo/mod/Makefile.in | 8 +- moo/mod/ffi.c | 306 +++++++++++++++++++++++++++++------------- moo/mod/icc.mak | 27 ++++ 16 files changed, 419 insertions(+), 219 deletions(-) create mode 100644 moo/kernel/Module.moo create mode 100644 moo/lib/icc.mak create mode 100644 moo/mod/icc.mak diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo index b435af6..c38d73e 100644 --- a/moo/kernel/FFI.moo +++ b/moo/kernel/FFI.moo @@ -1,69 +1,48 @@ +class(#byte) _FFI(Module) from 'ffi' +{ +} + class FFI(Object) { - dcl name handle funcs. + dcl name ffi funcs. method(#class) new: aString { ^self new open: aString. } - method open: aString + method initialize { self.funcs := Dictionary new. - self.name := aString. + self.ffi := _FFI new. + } - self.handle := self privateOpen: self.name. + method open: name + { + | x | + self.funcs removeAllKeys. + self.name := name. - "[ self.handle := self privateOpen: self.name ] - on: Exception do: [ - ] - on: XException do: [ - ]." + x := self.ffi open: name. + (x isError) ifTrue: [^x]. ^self. } method close { - self privateClose: self.handle. - self.handle := nil. + self.ffi close. } - method call: aFunctionName withSig: aString withArgs: anArray + method call: name signature: sig arguments: args { | 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. + f := self.funcs at: name. + (f isError) ifTrue: [ + f := self.ffi getsym: name. + (f isError) ifTrue: [^f]. + self.funcs at: name put: f. + ]. + ^self.ffi call: f sig: sig with: args } } diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index 0e03034..dcad1a1 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -41,7 +41,7 @@ class MyObject(Object) { method(#class) main { - | d a | + | d a ffi | (*k := Mill new. k register: #abc call: [ Dictionary new ]. @@ -83,5 +83,13 @@ class MyObject(Object) (*[ [Exception hash dump] ensure: ['xxxx' dump]. ] on: Exception do: [:ex | ('Exception caught - ' & ex asString) dump ].*) + + ffi := FFI new: '/lib64/libc.so.6'. + (ffi isError) + ifTrue: [System logNl: 'cannot open libc.so' ] + ifFalse: [ + (ffi call: #getpid signature: 'i' arguments: nil) dump. + ffi close. + ] } } diff --git a/moo/kernel/Module.moo b/moo/kernel/Module.moo new file mode 100644 index 0000000..60f4ae0 --- /dev/null +++ b/moo/kernel/Module.moo @@ -0,0 +1,18 @@ +class(#byte) Module(Object) +{ + method(#class) _newInstSize + { + self subclassResponsibility: #_newInstSize + } + + method(#class) new: size + { + ## ignore the specified size + ^(super new: (self _newInstSize)) + } + + method(#class) new + { + ^(super new: (self _newInstSize)) + } +} \ No newline at end of file diff --git a/moo/kernel/Moo.moo b/moo/kernel/Moo.moo index 6d20017..69c992c 100644 --- a/moo/kernel/Moo.moo +++ b/moo/kernel/Moo.moo @@ -8,7 +8,8 @@ #include 'Process.moo'. (* -------------------------------------------------------------------------- *) +#include 'Module.moo'. -(*#include 'FFI.moo'.*) +#include 'FFI.moo'. #include 'Stdio.moo'. #include 'Console.moo'. diff --git a/moo/kernel/Stdio.moo b/moo/kernel/Stdio.moo index 4bf8d38..247407a 100644 --- a/moo/kernel/Stdio.moo +++ b/moo/kernel/Stdio.moo @@ -1,4 +1,5 @@ -class(#byte) Stdio(Object) from 'stdio' + +class(#byte) Stdio(Module) from 'stdio' { dcl(#class) in out err. @@ -9,17 +10,6 @@ class(#byte) Stdio(Object) from 'stdio' * method close { } *) - method(#class) new: size - { - ## ignore the specified size - ^(super new: (self _newInstSize)) - } - - method(#class) new - { - ^(super new: (self _newInstSize)) - } - method(#class) open: name for: mode { ^(self new) open: name for: mode diff --git a/moo/lib/Makefile.am b/moo/lib/Makefile.am index 3ae3c90..0d2722e 100644 --- a/moo/lib/Makefile.am +++ b/moo/lib/Makefile.am @@ -60,7 +60,7 @@ 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-ffi -lmoo-console -lmoo-stdio endif bin_PROGRAMS = moo diff --git a/moo/lib/Makefile.in b/moo/lib/Makefile.in index 6298421..d092b01 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-ffi -lmoo-console -lmoo-stdio bin_PROGRAMS = moo$(EXEEXT) subdir = lib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ diff --git a/moo/lib/icc.mak b/moo/lib/icc.mak new file mode 100644 index 0000000..b72a158 --- /dev/null +++ b/moo/lib/icc.mak @@ -0,0 +1,38 @@ +# +# Intel 386(tm)/486(tm) C Code Builder(tm) Kit, Version 1.0 +# + +CFLAGS := /D__DOS__ /DMOO_ENABLE_STATIC_MODULE /DNDEBUG +LDFLAGS := /xnovm /xregion=12m + +SRCS := \ + bigint.c \ + comp.c \ + debug.c \ + decode.c \ + dic.c \ + err.c \ + exec.c \ + gc.c \ + heap.c \ + logfmt.c \ + moo.c \ + obj.c \ + proc.c \ + rbt.c \ + sym.c \ + utf8.c \ + utl.c \ + main.c \ + +OBJS := $(SRCS:.c=.obj) + +EXEFILE=moo.exe +MODFILE=..\mod\moomod.lib +RSPFILE := $(EXEFILE,B,S/.*/&.RSP/) + +all: $(OBJS) + echo $(OBJS) > $(RSPFILE) + echo $(MODFILE) >> $(RSPFILE) + echo $(LDFLAGS) >> $(RSPFILE) + $(CC) @$(RSPFILE) /e $(EXEFILE) diff --git a/moo/lib/main.c b/moo/lib/main.c index f975948..0b3194b 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -66,27 +66,27 @@ # endif #endif -#if !defined(MOO_DEFAULT_MODPREFIX) +#if !defined(MOO_DEFAULT_PFMODPREFIX) # if defined(_WIN32) -# define MOO_DEFAULT_MODPREFIX "moo-" +# define MOO_DEFAULT_PFMODPREFIX "moo-" # elif defined(__OS2__) -# define MOO_DEFAULT_MODPREFIX "moo" +# define MOO_DEFAULT_PFMODPREFIX "moo" # elif defined(__DOS__) -# define MOO_DEFAULT_MODPREFIX "moo" +# define MOO_DEFAULT_PFMODPREFIX "moo" # else -# define MOO_DEFAULT_MODPREFIX "libmoo-" +# define MOO_DEFAULT_PFMODPREFIX "libmoo-" # endif #endif -#if !defined(MOO_DEFAULT_MODPOSTFIX) +#if !defined(MOO_DEFAULT_PFMODPOSTFIX) # if defined(_WIN32) -# define MOO_DEFAULT_MODPOSTFIX "" +# define MOO_DEFAULT_PFMODPOSTFIX "" # elif defined(__OS2__) -# define MOO_DEFAULT_MODPOSTFIX "" +# define MOO_DEFAULT_PFMODPOSTFIX "" # elif defined(__DOS__) -# define MOO_DEFAULT_MODPOSTFIX "" +# define MOO_DEFAULT_PFMODPOSTFIX "" # else -# define MOO_DEFAULT_MODPOSTFIX "" +# define MOO_DEFAULT_PFMODPOSTFIX "" # endif #endif @@ -286,43 +286,54 @@ static moo_ooi_t input_handler (moo_t* moo, moo_iocmd_t cmd, moo_ioarg_t* arg) } /* ========================================================================= */ -static void* dl_open (moo_t* moo, const moo_ooch_t* name) +static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags) { #if defined(USE_LTDL) /* TODO: support various platforms */ moo_bch_t buf[1024]; /* TODO: use a proper path buffer */ moo_oow_t ucslen, bcslen; - moo_oow_t len; void* handle; -/* TODO: using MODPREFIX isn't a good idea for all kind of modules. - * OK to use it for a primitive module. - * NOT OK to use it for a FFI target. - * Attempting /home/hyung-hwan/xxx/lib/libmoo-libc.so.6 followed by libc.so.6 is bad. - * Need to accept the type or flags? - * - * dl_open (moo, "xxxx", MOO_MOD_EXTERNAL); - * if external, don't use DEFAULT_MODPERFIX and MODPOSTFIX??? - */ - - len = moo_copybcstr (buf, MOO_COUNTOF(buf), MOO_DEFAULT_MODPREFIX); - -/* TODO: proper error checking and overflow checking */ - bcslen = MOO_COUNTOF(buf) - len; - moo_convootobcstr (moo, name, &ucslen, &buf[len], &bcslen); - - moo_copybcstr (&buf[bcslen + len], MOO_COUNTOF(buf) - bcslen - len, MOO_DEFAULT_MODPOSTFIX); - - handle = lt_dlopenext (buf); - if (!handle) + if (flags & MOO_VMPRIM_OPENDL_PFMOD) { - buf[bcslen + len] = '\0'; - handle = lt_dlopenext (&buf[len]); - if (handle) MOO_DEBUG2 (moo, "Opened module file %s handle %p\n", &buf[len], handle); + moo_oow_t len; + + /* opening a primitive function module */ + len = moo_copybcstr (buf, MOO_COUNTOF(buf), MOO_DEFAULT_PFMODPREFIX); + + bcslen = MOO_COUNTOF(buf) - len; + if (moo_convootobcstr (moo, name, &ucslen, &buf[len], &bcslen) <= -1) return MOO_NULL; + + moo_copybcstr (&buf[bcslen + len], MOO_COUNTOF(buf) - bcslen - len, MOO_DEFAULT_PFMODPOSTFIX); + + handle = lt_dlopenext (buf); + if (!handle) + { + MOO_DEBUG3 (moo, "Failed to open(ext) DL %hs[%js] - %hs\n", buf, name, lt_dlerror()); + buf[bcslen + len] = '\0'; + handle = lt_dlopenext (&buf[len]); + if (!handle) MOO_DEBUG3 (moo, "Failed to open(ext) DL %hs[%js] - %s\n", &buf[len], name, lt_dlerror()); + else MOO_DEBUG3 (moo, "Opened(ext) DL %hs[%js] handle %p\n", &buf[len], name, handle); + } + else + { + MOO_DEBUG3 (moo, "Opened(ext) DL %hs[%js] handle %p\n", buf, name, handle); + } } else { - MOO_DEBUG2 (moo, "Opened module file %s handle %p\n", buf, handle); + /* opening a raw shared object */ + bcslen = MOO_COUNTOF(buf); + if (moo_convootobcstr (moo, name, &ucslen, buf, &bcslen) <= -1) return MOO_NULL; + handle = lt_dlopenext (buf); + if (!handle) + { + MOO_DEBUG2 (moo, "Failed to open(ext) DL %hs - %hs\n", buf, lt_dlerror()); + handle = lt_dlopen (buf); + if (!handle) MOO_DEBUG2 (moo, "Failed to open DL %hs - %s\n", buf, lt_dlerror()); + else MOO_DEBUG2 (moo, "Opened DL %hs handle %p\n", buf, handle); + } + else MOO_DEBUG2 (moo, "Opened(ext) DL %hs handle %p\n", buf, handle); } return handle; @@ -335,7 +346,7 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name) static void dl_close (moo_t* moo, void* handle) { - MOO_DEBUG1 (moo, "Closed module handle %p\n", handle); + MOO_DEBUG1 (moo, "Closed DL handle %p\n", handle); #if defined(USE_LTDL) lt_dlclose (handle); #elif defined(_WIN32) diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 4e3ed51..454db5b 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -44,6 +44,7 @@ * PUSH_CONTEXT, PUSH_INTLIT, PUSH_INTLIT, SEND_BLOCK_COPY */ #define MOO_USE_MAKE_BLOCK +#if !defined(NDEBUG) /* this is for gc debugging */ #define MOO_DEBUG_GC #define MOO_DEBUG_COMPILER @@ -51,6 +52,7 @@ /*#define MOO_DEBUG_VM_EXEC*/ #define MOO_DEBUG_BIGINT #define MOO_PROFILE_VM +#endif /* allow the caller to drive process switching by calling * moo_switchprocess(). */ @@ -929,25 +931,12 @@ moo_oop_t moo_instantiatewithtrailer ( /* ========================================================================= */ /* sym.c */ /* ========================================================================= */ -moo_oop_t moo_makesymbol ( - moo_t* moo, - const moo_ooch_t* ptr, - moo_oow_t len -); - moo_oop_t moo_findsymbol ( moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len ); -moo_oop_t moo_makestring ( - moo_t* moo, - const moo_ooch_t* ptr, - moo_oow_t len -); - - /* ========================================================================= */ /* dic.c */ /* ========================================================================= */ diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 9a6e627..1ae272f 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -350,6 +350,7 @@ void moo_freemem (moo_t* moo, void* ptr) #if defined(MOO_ENABLE_STATIC_MODULE) #include "../mod/console.h" +#include "../mod/_ffi.h" #include "../mod/_stdio.h" static struct @@ -360,7 +361,8 @@ static struct static_modtab[] = { { "console", moo_mod_console }, - { "stdio", moo_mod_stdio }, + { "ffi", moo_mod_ffi }, + { "stdio", moo_mod_stdio }, }; #endif @@ -450,7 +452,7 @@ moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namel moo_copyoochars ((moo_ooch_t*)md.mod.name, name, namelen); if (moo->vmprim.dl_open && moo->vmprim.dl_getsym && moo->vmprim.dl_close) { - md.handle = moo->vmprim.dl_open (moo, &buf[MOD_PREFIX_LEN]); + md.handle = moo->vmprim.dl_open (moo, &buf[MOD_PREFIX_LEN], MOO_VMPRIM_OPENDL_PFMOD); } if (md.handle == MOO_NULL) diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 951f85c..9b8c677 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -703,7 +703,13 @@ struct moo_heap_t /* ========================================================================= * VIRTUAL MACHINE PRIMITIVES * ========================================================================= */ -typedef void* (*moo_vmprim_opendl_t) (moo_t* moo, const moo_ooch_t* name); +enum moo_vmprim_opendl_flag_t +{ + MOO_VMPRIM_OPENDL_PFMOD = (1 << 0) +}; +typedef enum moo_vmprim_opendl_flag_t moo_vmprim_opendl_flag_t; + +typedef void* (*moo_vmprim_opendl_t) (moo_t* moo, const moo_ooch_t* name, int flags); typedef void (*moo_vmprim_closedl_t) (moo_t* moo, void* handle); typedef void* (*moo_vmprim_getdlsym_t) (moo_t* moo, void* handle, const moo_ooch_t* name); @@ -1277,7 +1283,24 @@ MOO_EXPORT int moo_invoke ( const moo_oocs_t* mthname ); -/* Temporary OOP management */ +/* ========================================================================= + * COMMON OBJECT MANAGEMENT FUNCTIONS + * ========================================================================= */ +MOO_EXPORT moo_oop_t moo_makesymbol ( + moo_t* moo, + const moo_ooch_t* ptr, + moo_oow_t len +); + +MOO_EXPORT moo_oop_t moo_makestring ( + moo_t* moo, + const moo_ooch_t* ptr, + moo_oow_t len +); + +/* ========================================================================= + * TEMPORARY OOP MANAGEMENT FUNCTIONS + * ========================================================================= */ MOO_EXPORT void moo_pushtmp ( moo_t* moo, moo_oop_t* oop_ptr diff --git a/moo/mod/Makefile.am b/moo/mod/Makefile.am index d730154..7ec0c5b 100644 --- a/moo/mod/Makefile.am +++ b/moo/mod/Makefile.am @@ -8,11 +8,11 @@ CPPFLAGS_COMMON = \ -I$(includedir) -fPIC if WIN32 -# you must adjust the value of DEFAULT_MODPOSTFIX according +# you must adjust the value of DEFAULT_PFMODPOSTFIX according # to the first number in -version-info above -CPPFLAGS_COMMON += -DMOO_DEFAULT_MODPREFIX=\"libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"-1\" +CPPFLAGS_COMMON += -DMOO_DEFAULT_PFMODPREFIX=\"libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"-1\" else -CPPFLAGS_COMMON += -DMOO_DEFAULT_MODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"\" +CPPFLAGS_COMMON += -DMOO_DEFAULT_PFMODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"\" endif if ENABLE_STATIC_MODULE @@ -20,7 +20,7 @@ if ENABLE_STATIC_MODULE ################################################## # STATIC MODULES BUILT INTO MAIN LIBRARY ################################################## -LDFLAGS_COMMON = +LDFLAGS_COMMON =-L$(libdir) -version-info 1:0:0 -no-undefined LIBADD_COMMON = noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la diff --git a/moo/mod/Makefile.in b/moo/mod/Makefile.in index f047098..06a1ead 100644 --- a/moo/mod/Makefile.in +++ b/moo/mod/Makefile.in @@ -79,10 +79,10 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -# you must adjust the value of DEFAULT_MODPOSTFIX according +# you must adjust the value of DEFAULT_PFMODPOSTFIX according # to the first number in -version-info above -@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=\"\" +@WIN32_TRUE@am__append_1 = -DMOO_DEFAULT_PFMODPREFIX=\"libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"-1\" +@WIN32_FALSE@am__append_2 = -DMOO_DEFAULT_PFMODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"\" subdir = mod DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/ac/depcomp @@ -397,7 +397,7 @@ CPPFLAGS_COMMON = -I$(abs_builddir) -I$(abs_builddir)/../lib \ ################################################## # STATIC MODULES BUILT INTO MAIN LIBRARY ################################################## -@ENABLE_STATIC_MODULE_TRUE@LDFLAGS_COMMON = +@ENABLE_STATIC_MODULE_TRUE@LDFLAGS_COMMON = -L$(libdir) -version-info 1:0:0 -no-undefined @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 diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index 2eb5c06..1843e4a 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -24,114 +24,126 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if 0 - #include "_ffi.h" #include -#if defined(USE_DYNCALL) +#include +#include + +#define HAVE_DYNCALL + +#if defined(HAVE_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) +typedef struct ffi_t ffi_t; +struct ffi_t { - moo_oop_t rcv, arg; + MOO_OBJ_HEADER; void* handle; +}; + +static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs) +{ + moo_ooi_t newinstsize = MOO_SIZEOF(ffi_t) - MOO_SIZEOF(moo_obj_t); + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize)); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) +{ +#if defined(HAVE_DYNCALL) + ffi_t* rcv; + moo_oop_t arg; MOO_ASSERT (moo, nargs == 1); - rcv = MOO_STACK_GETRCV(moo, nargs); + rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); arg = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR)) + if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR) || !MOO_OBJ_GET_FLAGS_EXTRA(arg)) /* TODO: better null check instead of FLAGS_EXTREA check */ { - /* TODO: more info on error */ - return MOO_PF_FAILURE; + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; } if (!moo->vmprim.dl_open) { - /* TODO: more info on error */ - return MOO_PF_FAILURE; + moo_seterrnum (moo, MOO_ENOIMPL); + goto reterr; } + rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)arg)->slot, 0); + if (!rcv->handle) goto reterr; -/* 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)); - + MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; + +reterr: + MOO_STACK_SETRETTOERROR (moo, nargs); + return MOO_PF_SUCCESS; +#else + moo_seterrnum (moo, MOO_ENOIMPL); + return MOO_PF_FAILURE; +#endif } -static moo_pfrc_t pf_ffi_close (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) { - moo_oop_t rcv, arg; - void* handle; +#if defined(HAVE_DYNCALL) + ffi_t* rcv; - MOO_ASSERT (moo, nargs == 1); + MOO_ASSERT (moo, nargs == 0); - rcv = MOO_STACK_GETRCV(moo, nargs); - arg = MOO_STACK_GETARG(moo, nargs, 0); + rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); - - if (!MOO_OOP_IS_SMOOI(arg)) + if (!moo->vmprim.dl_open) { - /* TODO: more info on error */ - return MOO_PF_FAILURE; + moo_seterrnum (moo, MOO_ENOIMPL); + return MOO_PF_SUCCESS; } - MOO_STACK_POP (moo); + moo->vmprim.dl_close (moo, rcv->handle); + rcv->handle = MOO_NULL; - 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); + MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; + +#else + moo_seterrnum (moo, MOO_ENOIMPL); + return MOO_PF_FAILURE; +#endif } -static moo_pfrc_t pf_ffi_call (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { -#if defined(USE_DYNCALL) - moo_oop_t rcv, fun, sig, args; +#if defined(HAVE_DYNCALL) + ffi_t* rcv; + moo_oop_t 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 */ + if (nargs < 3) { - /* TODO: more info on error */ - return MOO_PF_FAILURE; + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; } + rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + fun = MOO_STACK_GETARG(moo, nargs, 0); + sig = MOO_STACK_GETARG(moo, nargs, 1); + args = MOO_STACK_GETARG(moo, nargs, 2); + 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; + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; } - if (MOO_CLASSOF(moo,args) != moo->_array) /* TODO: check if arr is a kind of array??? or check if it's indexed */ + if (MOO_OBJ_GET_SIZE(sig) > 1 && 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_seterrnum (moo, MOO_EINVAL); + goto reterr; } { @@ -145,7 +157,11 @@ MOO_DEBUG0 (moo, "FFI: wrong signature...\n"); arr = (moo_oop_oop_t)args; dc = dcNewCallVM (4096); - if (!dc) return MOO_PF_HARD_FAILURE; /* TODO: proper error handling */ + if (!dc) + { + moo_seterrnum (moo, moo_syserrtoerrnum(errno)); + goto reterr; + } MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f); /*dcMode (dc, DC_CALL_C_DEFAULT); @@ -193,6 +209,9 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); break; +#if 0 + case 'B': /* byte array */ +#endif case 's': { moo_oow_t bcslen, ucslen; @@ -213,8 +232,6 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP } - MOO_STACK_POPS (moo, nargs); - switch (((moo_oop_char_t)sig)->slot[0]) { /* TODO: support more types... */ @@ -222,7 +239,7 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP case 'c': { char r = dcCallChar (dc, f); - MOO_STACK_SETTOP (moo, MOO_CHAR_TO_OOP(r)); + MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r)); break; } @@ -231,25 +248,31 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP 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)); + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(r)); break; } case 'l': { long r = dcCallLong (dc, f); - MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(r)); break; } case 'L': { long long r = dcCallLongLong (dc, f); - MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r)); + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(r)); break; } - case 's': +#if 0 + case 'b': /* byte array */ + { + } +#endif + + case 'B': { moo_oow_t bcslen, ucslen; moo_ooch_t ucs[1024]; @@ -257,21 +280,23 @@ MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MOD char* r = dcCallPointer (dc, f); bcslen = strlen(r); - moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* proper string conversion */ + moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* error check... */ - s = moo_makestring(moo, ucs, ucslen) + 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); + MOO_STACK_SETRET (moo, nargs, s); break; } default: - /* TOOD: ERROR HANDLING */ + + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; break; } @@ -279,48 +304,137 @@ MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MOD } return MOO_PF_SUCCESS; + +reterr: + MOO_STACK_SETRETTOERROR (moo, nargs); + return MOO_PF_SUCCESS; + #else + moo_seterrnum (moo, MOO_ENOIMPL); return MOO_PF_FAILURE; #endif } -static moo_pfrc_t pf_ffi_getsym (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs) { - moo_oop_t rcv, hnd, fun; +#if defined(HAVE_DYNCALL) + ffi_t* rcv; + moo_oop_t fun; void* sym; - MOO_ASSERT (moo, nargs == 2); + MOO_ASSERT (moo, nargs == 1); - 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; - } + rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + fun = MOO_STACK_GETARG(moo, nargs, 0); if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR)) { -MOO_DEBUG0 (moo, "wrong function name...\n"); - return MOO_PF_FAILURE; + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; } if (!moo->vmprim.dl_getsym) { - return MOO_PF_FAILURE; + moo_seterrnum (moo, MOO_ENOIMPL); + goto reterr; } - sym = moo->vmprim.dl_getsym (moo, (void*)MOO_OOP_TO_SMOOI(hnd), ((moo_oop_char_t)fun)->slot); - if (!sym) - { - return MOO_PF_FAILURE; - } + sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)fun)->slot); + if (!sym) goto reterr; /* TODO: how to hold an address? as an integer???? or a byte array? */ - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(sym)); - + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP((moo_oow_t)sym)); return MOO_PF_SUCCESS; -} + +reterr: + MOO_STACK_SETRETTOERROR (moo, nargs); + return MOO_PF_SUCCESS; + +#else + moo_seterrnum (moo, MOO_ENOIMPL); + return MOO_PF_FAILURE; #endif +} + +/* ------------------------------------------------------------------------ */ + +typedef struct fnctab_t fnctab_t; +struct fnctab_t +{ + moo_method_type_t type; + moo_ooch_t mthname[15]; + int variadic; + moo_pfimpl_t handler; +}; + +#define C MOO_METHOD_CLASS +#define I MOO_METHOD_INSTANCE + +static fnctab_t fnctab[] = +{ + { C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize }, + { I, { 'c','a','l','l','\0' }, 1, pf_call }, + { I, { 'c','a','l','l',':','s','i','g',':','w','i','t','h',':','\0' }, 0, pf_call }, + { I, { 'c','l','o','s','e','\0' }, 0, pf_close }, + { I, { 'g','e','t','s','y','m',':','\0' }, 0, pf_getsym }, + { I, { 'o','p','e','n',':','\0' }, 0, pf_open } +}; + +/* ------------------------------------------------------------------------ */ + +static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) +{ + int ret = 0; + moo_oow_t i; + + moo_pushtmp (moo, &_class); + for (i = 0; i < MOO_COUNTOF(fnctab); i++) + { + if (moo_genpfmethod (moo, mod, _class, fnctab[i].type, fnctab[i].mthname, fnctab[i].variadic, MOO_NULL) <= -1) + { + /* TODO: delete pfmethod generated??? */ + ret = -1; + break; + } + } + + moo_poptmp (moo); + return ret; +} + +static moo_pfimpl_t query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +{ + int left, right, mid, n; + + left = 0; right = MOO_COUNTOF(fnctab) - 1; + + while (left <= right) + { + mid = (left + right) / 2; + + n = moo_compoocstr (name, fnctab[mid].mthname); + if (n < 0) right = mid - 1; + else if (n > 0) left = mid + 1; + else + { + return fnctab[mid].handler; + } + } + + moo->errnum = MOO_ENOENT; + return MOO_NULL; +} + +static void unload (moo_t* moo, moo_mod_t* mod) +{ + /* TODO: close all open libraries...?? */ +} + +int moo_mod_ffi (moo_t* moo, moo_mod_t* mod) +{ + mod->import = import; + mod->query = query; + mod->unload = unload; + mod->ctx = MOO_NULL; + return 0; +} diff --git a/moo/mod/icc.mak b/moo/mod/icc.mak new file mode 100644 index 0000000..cad3756 --- /dev/null +++ b/moo/mod/icc.mak @@ -0,0 +1,27 @@ +# +# Intel 386(tm)/486(tm) C Code Builder(tm) Kit, Version 1.0 +# + +CFLAGS := /D__DOS__ /DMOO_ENABLE_STATIC_MODULE /DNDEBUG /I..\lib + +# ffi.c \ + +SRCS := \ + console.c \ + stdio.c + +OBJS := $(SRCS:.c=.obj) + +MODFILE=moomod.lib +RSPFILE := $(MODFILE,B,S/.*/&.RSP/) + +all: $(OBJS) + echo > $(RSPFILE) + !foreach x $(.NEWER) + modname /r $x >> $(RSPFILE) + !end + echo compress >> $(RSPFILE) + echo update >> $(RSPFILE) + echo quit exit >> $(RSPFILE) + del $(MODFILE) + lib32 $(MODFILE) batch < $(RSPFILE)