added MOO_VMPRIM_OPENDL_PFMOD.

started refactoring ffi handling code
This commit is contained in:
hyunghwan.chung 2017-01-10 10:50:26 +00:00
parent 95885e4dec
commit faf6ca28e5
16 changed files with 419 additions and 219 deletions

View File

@ -1,69 +1,48 @@
class(#byte) _FFI(Module) from 'ffi'
{
}
class FFI(Object) class FFI(Object)
{ {
dcl name handle funcs. dcl name ffi funcs.
method(#class) new: aString method(#class) new: aString
{ {
^self new open: aString. ^self new open: aString.
} }
method open: aString method initialize
{ {
self.funcs := Dictionary new. 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 ] x := self.ffi open: name.
on: Exception do: [ (x isError) ifTrue: [^x].
]
on: XException do: [
]."
^self. ^self.
} }
method close method close
{ {
self privateClose: self.handle. self.ffi close.
self.handle := nil.
} }
method call: aFunctionName withSig: aString withArgs: anArray method call: name signature: sig arguments: args
{ {
| f | | f |
f := self.funcs at: name.
## f := self.funcs at: aFunctionName. (f isError) ifTrue: [
## f isNil ifTrue: [ f := self.ffi getsym: name.
## f := self privateGetSymbol: aFunctionName in: self.handle. (f isError) ifTrue: [^f].
## f isNil ifTrue: [ self error: 'No such function' ]. self.funcs at: name put: f.
## self.funcs at: aFunctionName put: f. ].
## ]. ^self.ffi call: f sig: sig with: args
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
{
<primitive: #_ffi_open>
^nil. ## TODO: Error signal: 'can not open'
}
method privateClose: aHandle
{
<primitive: #_ffi_close>
}
method privateCall: aSymbol withSig: aString withArgs: anArray
{
<primitive: #_ffi_call>
}
method privateGetSymbol: aString in: aHandle
{
<primitive: #_ffi_getsym>
^nil.
} }
} }

View File

@ -41,7 +41,7 @@ class MyObject(Object)
{ {
method(#class) main method(#class) main
{ {
| d a | | d a ffi |
(*k := Mill new. (*k := Mill new.
k register: #abc call: [ Dictionary new ]. k register: #abc call: [ Dictionary new ].
@ -83,5 +83,13 @@ class MyObject(Object)
(*[ (*[
[Exception hash dump] ensure: ['xxxx' dump]. [Exception hash dump] ensure: ['xxxx' dump].
] on: Exception do: [:ex | ('Exception caught - ' & ex asString) 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.
]
} }
} }

18
moo/kernel/Module.moo Normal file
View File

@ -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))
}
}

View File

@ -8,7 +8,8 @@
#include 'Process.moo'. #include 'Process.moo'.
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
#include 'Module.moo'.
(*#include 'FFI.moo'.*) #include 'FFI.moo'.
#include 'Stdio.moo'. #include 'Stdio.moo'.
#include 'Console.moo'. #include 'Console.moo'.

View File

@ -1,4 +1,5 @@
class(#byte) Stdio(Object) from 'stdio'
class(#byte) Stdio(Module) from 'stdio'
{ {
dcl(#class) in out err. dcl(#class) in out err.
@ -9,17 +10,6 @@ class(#byte) Stdio(Object) from 'stdio'
* method close { <primitive: #stdio.close> } * method close { <primitive: #stdio.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 method(#class) open: name for: mode
{ {
^(self new) open: name for: mode ^(self new) open: name for: mode

View File

@ -60,7 +60,7 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON)
if ENABLE_STATIC_MODULE if ENABLE_STATIC_MODULE
libmoo_la_LDFLAGS += -L$(abs_builddir)/../mod 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 endif
bin_PROGRAMS = moo bin_PROGRAMS = moo

View File

@ -84,7 +84,7 @@ host_triplet = @host@
@WIN32_TRUE@am__append_1 = -DMOO_DEFAULT_MODPREFIX=\"libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"-1\" @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_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_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) bin_PROGRAMS = moo$(EXEEXT)
subdir = lib subdir = lib
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \

38
moo/lib/icc.mak Normal file
View File

@ -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)

View File

@ -66,27 +66,27 @@
# endif # endif
#endif #endif
#if !defined(MOO_DEFAULT_MODPREFIX) #if !defined(MOO_DEFAULT_PFMODPREFIX)
# if defined(_WIN32) # if defined(_WIN32)
# define MOO_DEFAULT_MODPREFIX "moo-" # define MOO_DEFAULT_PFMODPREFIX "moo-"
# elif defined(__OS2__) # elif defined(__OS2__)
# define MOO_DEFAULT_MODPREFIX "moo" # define MOO_DEFAULT_PFMODPREFIX "moo"
# elif defined(__DOS__) # elif defined(__DOS__)
# define MOO_DEFAULT_MODPREFIX "moo" # define MOO_DEFAULT_PFMODPREFIX "moo"
# else # else
# define MOO_DEFAULT_MODPREFIX "libmoo-" # define MOO_DEFAULT_PFMODPREFIX "libmoo-"
# endif # endif
#endif #endif
#if !defined(MOO_DEFAULT_MODPOSTFIX) #if !defined(MOO_DEFAULT_PFMODPOSTFIX)
# if defined(_WIN32) # if defined(_WIN32)
# define MOO_DEFAULT_MODPOSTFIX "" # define MOO_DEFAULT_PFMODPOSTFIX ""
# elif defined(__OS2__) # elif defined(__OS2__)
# define MOO_DEFAULT_MODPOSTFIX "" # define MOO_DEFAULT_PFMODPOSTFIX ""
# elif defined(__DOS__) # elif defined(__DOS__)
# define MOO_DEFAULT_MODPOSTFIX "" # define MOO_DEFAULT_PFMODPOSTFIX ""
# else # else
# define MOO_DEFAULT_MODPOSTFIX "" # define MOO_DEFAULT_PFMODPOSTFIX ""
# endif # endif
#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) #if defined(USE_LTDL)
/* TODO: support various platforms */ /* TODO: support various platforms */
moo_bch_t buf[1024]; /* TODO: use a proper path buffer */ moo_bch_t buf[1024]; /* TODO: use a proper path buffer */
moo_oow_t ucslen, bcslen; moo_oow_t ucslen, bcslen;
moo_oow_t len;
void* handle; void* handle;
/* TODO: using MODPREFIX isn't a good idea for all kind of modules. if (flags & MOO_VMPRIM_OPENDL_PFMOD)
* OK to use it for a primitive module. {
* NOT OK to use it for a FFI target. moo_oow_t len;
* 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); /* opening a primitive function module */
len = moo_copybcstr (buf, MOO_COUNTOF(buf), MOO_DEFAULT_PFMODPREFIX);
/* TODO: proper error checking and overflow checking */
bcslen = MOO_COUNTOF(buf) - len; bcslen = MOO_COUNTOF(buf) - len;
moo_convootobcstr (moo, name, &ucslen, &buf[len], &bcslen); 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_MODPOSTFIX); moo_copybcstr (&buf[bcslen + len], MOO_COUNTOF(buf) - bcslen - len, MOO_DEFAULT_PFMODPOSTFIX);
handle = lt_dlopenext (buf); handle = lt_dlopenext (buf);
if (!handle) if (!handle)
{ {
MOO_DEBUG3 (moo, "Failed to open(ext) DL %hs[%js] - %hs\n", buf, name, lt_dlerror());
buf[bcslen + len] = '\0'; buf[bcslen + len] = '\0';
handle = lt_dlopenext (&buf[len]); handle = lt_dlopenext (&buf[len]);
if (handle) MOO_DEBUG2 (moo, "Opened module file %s handle %p\n", &buf[len], handle); 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 else
{ {
MOO_DEBUG2 (moo, "Opened module file %s handle %p\n", buf, handle); MOO_DEBUG3 (moo, "Opened(ext) DL %hs[%js] handle %p\n", buf, name, handle);
}
}
else
{
/* 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; 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) 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) #if defined(USE_LTDL)
lt_dlclose (handle); lt_dlclose (handle);
#elif defined(_WIN32) #elif defined(_WIN32)

View File

@ -44,6 +44,7 @@
* PUSH_CONTEXT, PUSH_INTLIT, PUSH_INTLIT, SEND_BLOCK_COPY */ * PUSH_CONTEXT, PUSH_INTLIT, PUSH_INTLIT, SEND_BLOCK_COPY */
#define MOO_USE_MAKE_BLOCK #define MOO_USE_MAKE_BLOCK
#if !defined(NDEBUG)
/* this is for gc debugging */ /* this is for gc debugging */
#define MOO_DEBUG_GC #define MOO_DEBUG_GC
#define MOO_DEBUG_COMPILER #define MOO_DEBUG_COMPILER
@ -51,6 +52,7 @@
/*#define MOO_DEBUG_VM_EXEC*/ /*#define MOO_DEBUG_VM_EXEC*/
#define MOO_DEBUG_BIGINT #define MOO_DEBUG_BIGINT
#define MOO_PROFILE_VM #define MOO_PROFILE_VM
#endif
/* allow the caller to drive process switching by calling /* allow the caller to drive process switching by calling
* moo_switchprocess(). */ * moo_switchprocess(). */
@ -929,25 +931,12 @@ moo_oop_t moo_instantiatewithtrailer (
/* ========================================================================= */ /* ========================================================================= */
/* sym.c */ /* 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_oop_t moo_findsymbol (
moo_t* moo, moo_t* moo,
const moo_ooch_t* ptr, const moo_ooch_t* ptr,
moo_oow_t len moo_oow_t len
); );
moo_oop_t moo_makestring (
moo_t* moo,
const moo_ooch_t* ptr,
moo_oow_t len
);
/* ========================================================================= */ /* ========================================================================= */
/* dic.c */ /* dic.c */
/* ========================================================================= */ /* ========================================================================= */

View File

@ -350,6 +350,7 @@ void moo_freemem (moo_t* moo, void* ptr)
#if defined(MOO_ENABLE_STATIC_MODULE) #if defined(MOO_ENABLE_STATIC_MODULE)
#include "../mod/console.h" #include "../mod/console.h"
#include "../mod/_ffi.h"
#include "../mod/_stdio.h" #include "../mod/_stdio.h"
static struct static struct
@ -360,6 +361,7 @@ static struct
static_modtab[] = static_modtab[] =
{ {
{ "console", moo_mod_console }, { "console", moo_mod_console },
{ "ffi", moo_mod_ffi },
{ "stdio", moo_mod_stdio }, { "stdio", moo_mod_stdio },
}; };
#endif #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); moo_copyoochars ((moo_ooch_t*)md.mod.name, name, namelen);
if (moo->vmprim.dl_open && moo->vmprim.dl_getsym && moo->vmprim.dl_close) 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) if (md.handle == MOO_NULL)

View File

@ -703,7 +703,13 @@ struct moo_heap_t
/* ========================================================================= /* =========================================================================
* VIRTUAL MACHINE PRIMITIVES * 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_closedl_t) (moo_t* moo, void* handle);
typedef void* (*moo_vmprim_getdlsym_t) (moo_t* moo, void* handle, const moo_ooch_t* name); 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 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_EXPORT void moo_pushtmp (
moo_t* moo, moo_t* moo,
moo_oop_t* oop_ptr moo_oop_t* oop_ptr

View File

@ -8,11 +8,11 @@ CPPFLAGS_COMMON = \
-I$(includedir) -fPIC -I$(includedir) -fPIC
if WIN32 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 # 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 else
CPPFLAGS_COMMON += -DMOO_DEFAULT_MODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"\" CPPFLAGS_COMMON += -DMOO_DEFAULT_PFMODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"\"
endif endif
if ENABLE_STATIC_MODULE if ENABLE_STATIC_MODULE
@ -20,7 +20,7 @@ if ENABLE_STATIC_MODULE
################################################## ##################################################
# STATIC MODULES BUILT INTO MAIN LIBRARY # STATIC MODULES BUILT INTO MAIN LIBRARY
################################################## ##################################################
LDFLAGS_COMMON = LDFLAGS_COMMON =-L$(libdir) -version-info 1:0:0 -no-undefined
LIBADD_COMMON = LIBADD_COMMON =
noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la

View File

@ -79,10 +79,10 @@ POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ 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 # to the first number in -version-info above
@WIN32_TRUE@am__append_1 = -DMOO_DEFAULT_MODPREFIX=\"libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"-1\" @WIN32_TRUE@am__append_1 = -DMOO_DEFAULT_PFMODPREFIX=\"libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"-1\"
@WIN32_FALSE@am__append_2 = -DMOO_DEFAULT_MODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"\" @WIN32_FALSE@am__append_2 = -DMOO_DEFAULT_PFMODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_PFMODPOSTFIX=\"\"
subdir = mod subdir = mod
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/ac/depcomp $(top_srcdir)/ac/depcomp
@ -397,7 +397,7 @@ CPPFLAGS_COMMON = -I$(abs_builddir) -I$(abs_builddir)/../lib \
################################################## ##################################################
# STATIC MODULES BUILT INTO MAIN LIBRARY # 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_FALSE@LIBADD_COMMON = -lmoo
@ENABLE_STATIC_MODULE_TRUE@LIBADD_COMMON = @ENABLE_STATIC_MODULE_TRUE@LIBADD_COMMON =
@ENABLE_STATIC_MODULE_TRUE@noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la @ENABLE_STATIC_MODULE_TRUE@noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la

View File

@ -24,114 +24,126 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if 0
#include "_ffi.h" #include "_ffi.h"
#include <moo-utl.h> #include <moo-utl.h>
#if defined(USE_DYNCALL) #include <errno.h>
#include <string.h>
#define HAVE_DYNCALL
#if defined(HAVE_DYNCALL)
/* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ /* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */
# include <dyncall.h> /* TODO: remove this. make dyXXXX calls to callbacks */ # include <dyncall.h> /* TODO: remove this. make dyXXXX calls to callbacks */
#endif #endif
{ 1, 1, pf_ffi_open, "_ffi_open" }, typedef struct ffi_t ffi_t;
{ 1, 1, pf_ffi_close, "_ffi_close" }, struct ffi_t
{ 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; MOO_OBJ_HEADER;
void* handle; 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); 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); 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 */ moo_seterrnum (moo, MOO_EINVAL);
return MOO_PF_FAILURE; goto reterr;
} }
if (!moo->vmprim.dl_open) if (!moo->vmprim.dl_open)
{ {
/* TODO: more info on error */ moo_seterrnum (moo, MOO_ENOIMPL);
return MOO_PF_FAILURE; 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... */ MOO_STACK_SETRETTORCV (moo, nargs);
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; 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; #if defined(HAVE_DYNCALL)
void* handle; ffi_t* rcv;
MOO_ASSERT (moo, nargs == 1); MOO_ASSERT (moo, nargs == 0);
rcv = MOO_STACK_GETRCV(moo, nargs); rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
if (!moo->vmprim.dl_open)
if (!MOO_OOP_IS_SMOOI(arg))
{ {
/* TODO: more info on error */ moo_seterrnum (moo, MOO_ENOIMPL);
return MOO_PF_FAILURE; 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 */ MOO_STACK_SETRETTORCV (moo, nargs);
if (moo->vmprim.dl_close) moo->vmprim.dl_close (moo, handle);
return MOO_PF_SUCCESS; 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) #if defined(HAVE_DYNCALL)
moo_oop_t rcv, fun, sig, args; ffi_t* rcv;
moo_oop_t fun, sig, args;
MOO_ASSERT (moo, nargs == 3); if (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 */ moo_seterrnum (moo, MOO_EINVAL);
return MOO_PF_FAILURE; 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) if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0)
{ {
MOO_DEBUG0 (moo, "FFI: wrong signature...\n"); moo_seterrnum (moo, MOO_EINVAL);
return MOO_PF_FAILURE; 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 */ moo_seterrnum (moo, MOO_EINVAL);
return MOO_PF_FAILURE; goto reterr;
} }
{ {
@ -145,7 +157,11 @@ MOO_DEBUG0 (moo, "FFI: wrong signature...\n");
arr = (moo_oop_oop_t)args; arr = (moo_oop_oop_t)args;
dc = dcNewCallVM (4096); 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); MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f);
/*dcMode (dc, DC_CALL_C_DEFAULT); /*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])); dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break; break;
#if 0
case 'B': /* byte array */
#endif
case 's': case 's':
{ {
moo_oow_t bcslen, ucslen; 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]) switch (((moo_oop_char_t)sig)->slot[0])
{ {
/* TODO: support more types... */ /* 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': case 'c':
{ {
char r = dcCallChar (dc, f); 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; 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); int r = dcCallInt (dc, f);
MOO_DEBUG1 (moo, "CALLED... %d\n", r); MOO_DEBUG1 (moo, "CALLED... %d\n", r);
MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE); 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; break;
} }
case 'l': case 'l':
{ {
long r = dcCallLong (dc, f); 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; break;
} }
case 'L': case 'L':
{ {
long long r = dcCallLongLong (dc, f); 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; break;
} }
case 's': #if 0
case 'b': /* byte array */
{
}
#endif
case 'B':
{ {
moo_oow_t bcslen, ucslen; moo_oow_t bcslen, ucslen;
moo_ooch_t ucs[1024]; 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); char* r = dcCallPointer (dc, f);
bcslen = strlen(r); 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) if (!s)
{ {
dcFree (dc); dcFree (dc);
return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */ return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */
} }
MOO_STACK_SETTOP (moo, s); MOO_STACK_SETRET (moo, nargs, s);
break; break;
} }
default: default:
/* TOOD: ERROR HANDLING */
moo_seterrnum (moo, MOO_EINVAL);
goto reterr;
break; break;
} }
@ -279,48 +304,137 @@ MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MOD
} }
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
reterr:
MOO_STACK_SETRETTOERROR (moo, nargs);
return MOO_PF_SUCCESS;
#else #else
moo_seterrnum (moo, MOO_ENOIMPL);
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
#endif #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; void* sym;
MOO_ASSERT (moo, nargs == 2); MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GET(moo, moo->sp - 2); rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
fun = MOO_STACK_GET(moo, moo->sp - 1); fun = MOO_STACK_GETARG(moo, nargs, 0);
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)) if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR))
{ {
MOO_DEBUG0 (moo, "wrong function name...\n"); moo_seterrnum (moo, MOO_EINVAL);
return MOO_PF_FAILURE; goto reterr;
} }
if (!moo->vmprim.dl_getsym) 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); sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)fun)->slot);
if (!sym) if (!sym) goto reterr;
{
return MOO_PF_FAILURE;
}
/* TODO: how to hold an address? as an integer???? or a byte array? */ /* 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; 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 #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;
}

27
moo/mod/icc.mak Normal file
View File

@ -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)