added MOO_VMPRIM_OPENDL_PFMOD.
started refactoring ffi handling code
This commit is contained in:
parent
95885e4dec
commit
faf6ca28e5
@ -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
|
||||
{
|
||||
<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.
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
]
|
||||
}
|
||||
}
|
||||
|
18
moo/kernel/Module.moo
Normal file
18
moo/kernel/Module.moo
Normal 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))
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@
|
||||
#include 'Process.moo'.
|
||||
|
||||
(* -------------------------------------------------------------------------- *)
|
||||
#include 'Module.moo'.
|
||||
|
||||
(*#include 'FFI.moo'.*)
|
||||
#include 'FFI.moo'.
|
||||
#include 'Stdio.moo'.
|
||||
#include 'Console.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 { <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
|
||||
{
|
||||
^(self new) open: name for: mode
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
38
moo/lib/icc.mak
Normal file
38
moo/lib/icc.mak
Normal 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)
|
@ -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)
|
||||
|
@ -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 */
|
||||
/* ========================================================================= */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
306
moo/mod/ffi.c
306
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 <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 */
|
||||
# include <dyncall.h> /* 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;
|
||||
}
|
||||
|
27
moo/mod/icc.mak
Normal file
27
moo/mod/icc.mak
Normal 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)
|
Loading…
Reference in New Issue
Block a user