started taking ffi out of the main vm, putting it to a separate module

This commit is contained in:
hyunghwan.chung 2017-01-09 13:41:11 +00:00
parent 2528dcdbe5
commit 65f2f862f8
9 changed files with 505 additions and 419 deletions

69
moo/kernel/FFI.moo Normal file
View File

@ -0,0 +1,69 @@
class FFI(Object)
{
dcl name handle funcs.
method(#class) new: aString
{
^self new open: aString.
}
method open: aString
{
self.funcs := Dictionary new.
self.name := aString.
self.handle := self privateOpen: self.name.
"[ self.handle := self privateOpen: self.name ]
on: Exception do: [
]
on: XException do: [
]."
^self.
}
method close
{
self privateClose: self.handle.
self.handle := nil.
}
method call: aFunctionName withSig: aString withArgs: anArray
{
| f |
## f := self.funcs at: aFunctionName.
## f isNil ifTrue: [
## f := self privateGetSymbol: aFunctionName in: self.handle.
## f isNil ifTrue: [ self error: 'No such function' ].
## self.funcs at: aFunctionName put: f.
## ].
f := self privateGetSymbol: aFunctionName in: self.handle.
f isNil ifTrue: [ self error: 'No such function' ].
^self privateCall: f withSig: aString withArgs: anArray
}
method privateOpen: aString
{
<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

@ -9,77 +9,6 @@
(* -------------------------------------------------------------------------- *)
class FFI(Object)
{
dcl name handle funcs.
method(#class) new: aString
{
^self new open: aString.
}
method open: aString
{
self.funcs := Dictionary new.
self.name := aString.
self.handle := self privateOpen: self.name.
"[ self.handle := self privateOpen: self.name ]
on: Exception do: [
]
on: XException do: [
]."
^self.
}
method close
{
self privateClose: self.handle.
self.handle := nil.
}
method call: aFunctionName withSig: aString withArgs: anArray
{
| f |
## f := self.funcs at: aFunctionName.
## f isNil ifTrue: [
## f := self privateGetSymbol: aFunctionName in: self.handle.
## f isNil ifTrue: [ self error: 'No such function' ].
## self.funcs at: aFunctionName put: f.
## ].
f := self privateGetSymbol: aFunctionName in: self.handle.
f isNil ifTrue: [ self error: 'No such function' ].
^self privateCall: f withSig: aString withArgs: anArray
}
method privateOpen: aString
{
<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.
}
}
(* -------------------------------------------------------------------------- *)
(*#include 'FFI.moo'.*)
#include 'Stdio.moo'.
#include 'Console.moo'.

View File

@ -60,14 +60,14 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON)
if ENABLE_STATIC_MODULE
libmoo_la_LDFLAGS += -L$(abs_builddir)/../mod
libmoo_la_LIBADD += -lmoo-console -lmoo-stdio -ltermcap
libmoo_la_LIBADD += -lmoo-console -lmoo-stdio #-ltermcap
endif
bin_PROGRAMS = moo
moo_SOURCES = main.c
moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
moo_LDFLAGS = $(LDFLAGS_LIB_COMMON)
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo #-ldyncall_s
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo
install-data-hook:

View File

@ -84,7 +84,7 @@ host_triplet = @host@
@WIN32_TRUE@am__append_1 = -DMOO_DEFAULT_MODPREFIX=\"libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"-1\"
@WIN32_FALSE@am__append_2 = -DMOO_DEFAULT_MODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"\"
@ENABLE_STATIC_MODULE_TRUE@am__append_3 = -L$(abs_builddir)/../mod
@ENABLE_STATIC_MODULE_TRUE@am__append_4 = -lmoo-console -lmoo-stdio -ltermcap
@ENABLE_STATIC_MODULE_TRUE@am__append_4 = -lmoo-console -lmoo-stdio #-ltermcap
bin_PROGRAMS = moo$(EXEEXT)
subdir = lib
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
@ -430,7 +430,7 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_4)
moo_SOURCES = main.c
moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
moo_LDFLAGS = $(LDFLAGS_LIB_COMMON)
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo #-ldyncall_s
moo_LDADD = $(LIBADD_LIB_COMMON) -lmoo
all: moo-cfg.h
$(MAKE) $(AM_MAKEFLAGS) all-am

View File

@ -50,11 +50,6 @@
# endif
#endif
#if defined(USE_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
#define PROC_STATE_RUNNING 3
#define PROC_STATE_WAITING 2
@ -76,7 +71,6 @@
(MOO_OOP_TO_SMOOI((x)->heap_ftime_sec) == MOO_OOP_TO_SMOOI((y)->heap_ftime_sec) && MOO_OOP_TO_SMOOI((x)->heap_ftime_nsec) < MOO_OOP_TO_SMOOI((y)->heap_ftime_nsec)) \
)
#define LOAD_IP(moo, v_ctx) ((moo)->ip = MOO_OOP_TO_SMOOI((v_ctx)->ip))
#define STORE_IP(moo, v_ctx) ((v_ctx)->ip = MOO_SMOOI_TO_OOP((moo)->ip))
@ -2658,287 +2652,6 @@ static moo_pfrc_t pf_error_as_string (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_ffi_open (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg;
void* handle;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR))
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
if (!moo->vmprim.dl_open)
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
/* TODO: check null-termination... */
handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)arg)->slot);
if (!handle)
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
MOO_STACK_POP (moo);
/* TODO: how to hold an address? as an integer???? or a byte array? fix this not to loose accuracy*/
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(handle));
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_ffi_close (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg;
void* handle;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_OOP_IS_SMOOI(arg))
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
MOO_STACK_POP (moo);
handle = (void*)MOO_OOP_TO_SMOOI(arg); /* TODO: how to store void* ???. fix this not to loose accuracy */
if (moo->vmprim.dl_close) moo->vmprim.dl_close (moo, handle);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_ffi_call (moo_t* moo, moo_ooi_t nargs)
{
#if defined(USE_DYNCALL)
moo_oop_t rcv, fun, sig, args;
MOO_ASSERT (moo, nargs == 3);
rcv = MOO_STACK_GET(moo, moo->sp - 3);
fun = MOO_STACK_GET(moo, moo->sp - 2);
sig = MOO_STACK_GET(moo, moo->sp - 1);
args = MOO_STACK_GET(moo, moo->sp);
if (!MOO_OOP_IS_SMOOI(fun)) /* TODO: how to store pointer */
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0)
{
MOO_DEBUG0 (moo, "FFI: wrong signature...\n");
return MOO_PF_FAILURE;
}
if (MOO_CLASSOF(moo,args) != moo->_array) /* TODO: check if arr is a kind of array??? or check if it's indexed */
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
{
moo_oow_t i;
DCCallVM* dc;
void* f;
moo_oop_oop_t arr;
int mode_set;
f = MOO_OOP_TO_SMOOI(fun); /* TODO: decode pointer properly */
arr = (moo_oop_oop_t)args;
dc = dcNewCallVM (4096);
if (!dc) return MOO_PF_HARD_FAILURE; /* TODO: proper error handling */
MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f);
/*dcMode (dc, DC_CALL_C_DEFAULT);
dcReset (dc);*/
/*for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++)
{
if (((moo_oop_char_t)sig)->slot[i] == '|')
{
dcMode (dc, DC_CALL_C_ELLIPSIS);
MOO_DEBUG0 (moo, "CALL MODE 111 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
mode_set = 1;
break;
}
}
if (!mode_set) */ dcMode (dc, DC_CALL_C_DEFAULT);
for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++)
{
MOO_DEBUG1 (moo, "FFI: CALLING ARG %c\n", ((moo_oop_char_t)sig)->slot[i]);
switch (((moo_oop_char_t)sig)->slot[i])
{
/* TODO: support more types... */
/*
case '|':
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS);
MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
break;
*/
case 'c':
/* TODO: sanity check on the argument type */
dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 2]));
break;
case 'i':
dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break;
case 'l':
dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break;
case 'L':
dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break;
case 's':
{
moo_oow_t bcslen, ucslen;
moo_bch_t bcs[1024];
ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 2]);
moo_convootobchars (moo, ((moo_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */
bcs[bcslen] = '\0';
dcArgPointer (dc, bcs);
break;
}
default:
/* TODO: ERROR HANDLING */
break;
}
}
MOO_STACK_POPS (moo, nargs);
switch (((moo_oop_char_t)sig)->slot[0])
{
/* TODO: support more types... */
/* TODO: proper return value conversion */
case 'c':
{
char r = dcCallChar (dc, f);
MOO_STACK_SETTOP (moo, MOO_CHAR_TO_OOP(r));
break;
}
case 'i':
{
int r = dcCallInt (dc, f);
MOO_DEBUG1 (moo, "CALLED... %d\n", r);
MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r));
break;
}
case 'l':
{
long r = dcCallLong (dc, f);
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r));
break;
}
case 'L':
{
long long r = dcCallLongLong (dc, f);
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r));
break;
}
case 's':
{
moo_oow_t bcslen, ucslen;
moo_ooch_t ucs[1024];
moo_oop_t s;
char* r = dcCallPointer (dc, f);
bcslen = strlen(r);
moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* proper string conversion */
s = moo_makestring(moo, ucs, ucslen)
if (!s)
{
dcFree (dc);
return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */
}
MOO_STACK_SETTOP (moo, s);
break;
}
default:
/* TOOD: ERROR HANDLING */
break;
}
dcFree (dc);
}
return MOO_PF_SUCCESS;
#else
return MOO_PF_FAILURE;
#endif
}
static moo_pfrc_t pf_ffi_getsym (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, hnd, fun;
void* sym;
MOO_ASSERT (moo, nargs == 2);
rcv = MOO_STACK_GET(moo, moo->sp - 2);
fun = MOO_STACK_GET(moo, moo->sp - 1);
hnd = MOO_STACK_GET(moo, moo->sp);
if (!MOO_OOP_IS_SMOOI(hnd)) /* TODO: how to store pointer */
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR))
{
MOO_DEBUG0 (moo, "wrong function name...\n");
return MOO_PF_FAILURE;
}
if (!moo->vmprim.dl_getsym)
{
return MOO_PF_FAILURE;
}
sym = moo->vmprim.dl_getsym (moo, (void*)MOO_OOP_TO_SMOOI(hnd), ((moo_oop_char_t)fun)->slot);
if (!sym)
{
return MOO_PF_FAILURE;
}
/* TODO: how to hold an address? as an integer???? or a byte array? */
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(sym));
return MOO_PF_SUCCESS;
}
#define MAX_NARGS MOO_TYPE_MAX(moo_ooi_t)
struct pf_t
@ -3019,13 +2732,7 @@ static pf_t pftab[] =
{ 0, 0, pf_error_as_character, "_error_as_character" },
{ 0, 0, pf_error_as_integer, "_error_as_integer" },
{ 0, 0, pf_error_as_string, "_error_as_string" },
{ 1, 1, pf_ffi_open, "_ffi_open" },
{ 1, 1, pf_ffi_close, "_ffi_close" },
{ 2, 2, pf_ffi_getsym, "_ffi_getsym" },
{ 3, 3, pf_ffi_call, "_ffi_call" }
{ 0, 0, pf_error_as_string, "_error_as_string" }
};
int moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len)

View File

@ -20,14 +20,10 @@ if ENABLE_STATIC_MODULE
##################################################
# STATIC MODULES BUILT INTO MAIN LIBRARY
##################################################
LDFLAGS_COMMON =
LIBADD_COMMON =
noinst_LTLIBRARIES = libmoo-console.la libmoo-stdio.la
libmoo_console_la_SOURCES = console.c
libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_stdio_la_SOURCES = stdio.c
libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON)
noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la
else
@ -38,19 +34,22 @@ LDFLAGS_COMMON = -L$(abs_builddir)/../lib -L$(libdir) -version-info 1:0:0 -no-un
LIBADD_COMMON = -lmoo
pkgmodexecdir = $(libdir)
pkgmodexec_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la
pkgmodexec_LTLIBRARIES = libmoo-stdio.la libmoo-console.la
libmoo_stdio_la_SOURCES = stdio.c _stdio.h
libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_stdio_la_LIBADD = $(LIBADD_COMMON)
endif
libmoo_console_la_SOURCES = console.c console.h
libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_console_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_console_la_LIBADD = $(LIBADD_COMMON) -ltermcap
endif
libmoo_ffi_la_SOURCES = ffi.c _ffi.h
libmoo_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_ffi_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_ffi_la_LIBADD = $(LIBADD_COMMON) -ldyncall_s
libmoo_stdio_la_SOURCES = stdio.c _stdio.h
libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_stdio_la_LIBADD = $(LIBADD_COMMON)

View File

@ -129,13 +129,8 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(pkgmodexecdir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkgmodexec_LTLIBRARIES)
am__DEPENDENCIES_1 =
@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_DEPENDENCIES = \
@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1)
am__libmoo_console_la_SOURCES_DIST = console.c console.h
@ENABLE_STATIC_MODULE_FALSE@am_libmoo_console_la_OBJECTS = \
@ENABLE_STATIC_MODULE_FALSE@ libmoo_console_la-console.lo
@ENABLE_STATIC_MODULE_TRUE@am_libmoo_console_la_OBJECTS = \
@ENABLE_STATIC_MODULE_TRUE@ libmoo_console_la-console.lo
libmoo_console_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libmoo_console_la_OBJECTS = libmoo_console_la-console.lo
libmoo_console_la_OBJECTS = $(am_libmoo_console_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -148,13 +143,17 @@ libmoo_console_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@ENABLE_STATIC_MODULE_FALSE@am_libmoo_console_la_rpath = -rpath \
@ENABLE_STATIC_MODULE_FALSE@ $(pkgmodexecdir)
@ENABLE_STATIC_MODULE_TRUE@am_libmoo_console_la_rpath =
@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_DEPENDENCIES = \
@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1)
am__libmoo_stdio_la_SOURCES_DIST = stdio.c _stdio.h
@ENABLE_STATIC_MODULE_FALSE@am_libmoo_stdio_la_OBJECTS = \
@ENABLE_STATIC_MODULE_FALSE@ libmoo_stdio_la-stdio.lo
@ENABLE_STATIC_MODULE_TRUE@am_libmoo_stdio_la_OBJECTS = \
@ENABLE_STATIC_MODULE_TRUE@ libmoo_stdio_la-stdio.lo
libmoo_ffi_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libmoo_ffi_la_OBJECTS = libmoo_ffi_la-ffi.lo
libmoo_ffi_la_OBJECTS = $(am_libmoo_ffi_la_OBJECTS)
libmoo_ffi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libmoo_ffi_la_LDFLAGS) $(LDFLAGS) -o $@
@ENABLE_STATIC_MODULE_FALSE@am_libmoo_ffi_la_rpath = -rpath \
@ENABLE_STATIC_MODULE_FALSE@ $(pkgmodexecdir)
@ENABLE_STATIC_MODULE_TRUE@am_libmoo_ffi_la_rpath =
libmoo_stdio_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libmoo_stdio_la_OBJECTS = libmoo_stdio_la-stdio.lo
libmoo_stdio_la_OBJECTS = $(am_libmoo_stdio_la_OBJECTS)
libmoo_stdio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
@ -197,9 +196,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libmoo_console_la_SOURCES) $(libmoo_stdio_la_SOURCES)
DIST_SOURCES = $(am__libmoo_console_la_SOURCES_DIST) \
$(am__libmoo_stdio_la_SOURCES_DIST)
SOURCES = $(libmoo_console_la_SOURCES) $(libmoo_ffi_la_SOURCES) \
$(libmoo_stdio_la_SOURCES)
DIST_SOURCES = $(libmoo_console_la_SOURCES) $(libmoo_ffi_la_SOURCES) \
$(libmoo_stdio_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@ -389,30 +389,32 @@ CPPFLAGS_COMMON = -I$(abs_builddir) -I$(abs_builddir)/../lib \
-I$(abs_srcdir) -I$(abs_srcdir)/../lib -I$(includedir) -fPIC \
$(am__append_1) $(am__append_2)
##################################################
# STATIC MODULES BUILT INTO MAIN LIBRARY
##################################################
@ENABLE_STATIC_MODULE_TRUE@noinst_LTLIBRARIES = libmoo-console.la libmoo-stdio.la
@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_SOURCES = console.c console.h
@ENABLE_STATIC_MODULE_TRUE@libmoo_console_la_SOURCES = console.c
@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON)
@ENABLE_STATIC_MODULE_TRUE@libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON)
@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_SOURCES = stdio.c _stdio.h
@ENABLE_STATIC_MODULE_TRUE@libmoo_stdio_la_SOURCES = stdio.c
@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON)
@ENABLE_STATIC_MODULE_TRUE@libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON)
##################################################
# DYNAMIC MODULES
##################################################
@ENABLE_STATIC_MODULE_FALSE@LDFLAGS_COMMON = -L$(abs_builddir)/../lib -L$(libdir) -version-info 1:0:0 -no-undefined
##################################################
# STATIC MODULES BUILT INTO MAIN LIBRARY
##################################################
@ENABLE_STATIC_MODULE_TRUE@LDFLAGS_COMMON =
@ENABLE_STATIC_MODULE_FALSE@LIBADD_COMMON = -lmoo
@ENABLE_STATIC_MODULE_TRUE@LIBADD_COMMON =
@ENABLE_STATIC_MODULE_TRUE@noinst_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la
@ENABLE_STATIC_MODULE_FALSE@pkgmodexecdir = $(libdir)
@ENABLE_STATIC_MODULE_FALSE@pkgmodexec_LTLIBRARIES = libmoo-stdio.la libmoo-console.la
@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON)
@ENABLE_STATIC_MODULE_FALSE@libmoo_stdio_la_LIBADD = $(LIBADD_COMMON)
@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_LDFLAGS = $(LDFLAGS_COMMON)
@ENABLE_STATIC_MODULE_FALSE@libmoo_console_la_LIBADD = $(LIBADD_COMMON) -ltermcap
@ENABLE_STATIC_MODULE_FALSE@pkgmodexec_LTLIBRARIES = libmoo-console.la libmoo-ffi.la libmoo-stdio.la
libmoo_console_la_SOURCES = console.c console.h
libmoo_console_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_console_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_console_la_LIBADD = $(LIBADD_COMMON) -ltermcap
libmoo_ffi_la_SOURCES = ffi.c _ffi.h
libmoo_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_ffi_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_ffi_la_LIBADD = $(LIBADD_COMMON) -ldyncall_s
libmoo_stdio_la_SOURCES = stdio.c _stdio.h
libmoo_stdio_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_stdio_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_stdio_la_LIBADD = $(LIBADD_COMMON)
all: all-am
.SUFFIXES:
@ -497,6 +499,9 @@ clean-pkgmodexecLTLIBRARIES:
libmoo-console.la: $(libmoo_console_la_OBJECTS) $(libmoo_console_la_DEPENDENCIES) $(EXTRA_libmoo_console_la_DEPENDENCIES)
$(AM_V_CCLD)$(libmoo_console_la_LINK) $(am_libmoo_console_la_rpath) $(libmoo_console_la_OBJECTS) $(libmoo_console_la_LIBADD) $(LIBS)
libmoo-ffi.la: $(libmoo_ffi_la_OBJECTS) $(libmoo_ffi_la_DEPENDENCIES) $(EXTRA_libmoo_ffi_la_DEPENDENCIES)
$(AM_V_CCLD)$(libmoo_ffi_la_LINK) $(am_libmoo_ffi_la_rpath) $(libmoo_ffi_la_OBJECTS) $(libmoo_ffi_la_LIBADD) $(LIBS)
libmoo-stdio.la: $(libmoo_stdio_la_OBJECTS) $(libmoo_stdio_la_DEPENDENCIES) $(EXTRA_libmoo_stdio_la_DEPENDENCIES)
$(AM_V_CCLD)$(libmoo_stdio_la_LINK) $(am_libmoo_stdio_la_rpath) $(libmoo_stdio_la_OBJECTS) $(libmoo_stdio_la_LIBADD) $(LIBS)
@ -507,6 +512,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_console_la-console.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_ffi_la-ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_stdio_la-stdio.Plo@am__quote@
.c.o:
@ -540,6 +546,13 @@ libmoo_console_la-console.lo: console.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_console_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_console_la-console.lo `test -f 'console.c' || echo '$(srcdir)/'`console.c
libmoo_ffi_la-ffi.lo: ffi.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_ffi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_ffi_la-ffi.lo -MD -MP -MF $(DEPDIR)/libmoo_ffi_la-ffi.Tpo -c -o libmoo_ffi_la-ffi.lo `test -f 'ffi.c' || echo '$(srcdir)/'`ffi.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_ffi_la-ffi.Tpo $(DEPDIR)/libmoo_ffi_la-ffi.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ffi.c' object='libmoo_ffi_la-ffi.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_ffi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_ffi_la-ffi.lo `test -f 'ffi.c' || echo '$(srcdir)/'`ffi.c
libmoo_stdio_la-stdio.lo: stdio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_stdio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_stdio_la-stdio.lo -MD -MP -MF $(DEPDIR)/libmoo_stdio_la-stdio.Tpo -c -o libmoo_stdio_la-stdio.lo `test -f 'stdio.c' || echo '$(srcdir)/'`stdio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_stdio_la-stdio.Tpo $(DEPDIR)/libmoo_stdio_la-stdio.Plo

43
moo/mod/_ffi.h Normal file
View File

@ -0,0 +1,43 @@
/*
* $Id$
*
Copyright (c) 2006-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MOO_LIB_MOD_FFI_H_
#define _MOO_LIB_MOD_FFI_H_
#include <moo.h>
#if defined(__cplusplus)
extern "C" {
#endif
MOO_EXPORT int moo_mod_ffi (moo_t* moo, moo_mod_t* mod);
#if defined(__cplusplus)
}
#endif
#endif

326
moo/mod/ffi.c Normal file
View File

@ -0,0 +1,326 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if 0
#include "_ffi.h"
#include <moo-utl.h>
#if defined(USE_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)
{
moo_oop_t rcv, arg;
void* handle;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR))
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
if (!moo->vmprim.dl_open)
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
/* TODO: check null-termination... */
handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)arg)->slot);
if (!handle)
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
MOO_STACK_POP (moo);
/* TODO: how to hold an address? as an integer???? or a byte array? fix this not to loose accuracy*/
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(handle));
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_ffi_close (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg;
void* handle;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_OOP_IS_SMOOI(arg))
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
MOO_STACK_POP (moo);
handle = (void*)MOO_OOP_TO_SMOOI(arg); /* TODO: how to store void* ???. fix this not to loose accuracy */
if (moo->vmprim.dl_close) moo->vmprim.dl_close (moo, handle);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_ffi_call (moo_t* moo, moo_ooi_t nargs)
{
#if defined(USE_DYNCALL)
moo_oop_t rcv, fun, sig, args;
MOO_ASSERT (moo, nargs == 3);
rcv = MOO_STACK_GET(moo, moo->sp - 3);
fun = MOO_STACK_GET(moo, moo->sp - 2);
sig = MOO_STACK_GET(moo, moo->sp - 1);
args = MOO_STACK_GET(moo, moo->sp);
if (!MOO_OOP_IS_SMOOI(fun)) /* TODO: how to store pointer */
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0)
{
MOO_DEBUG0 (moo, "FFI: wrong signature...\n");
return MOO_PF_FAILURE;
}
if (MOO_CLASSOF(moo,args) != moo->_array) /* TODO: check if arr is a kind of array??? or check if it's indexed */
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
{
moo_oow_t i;
DCCallVM* dc;
void* f;
moo_oop_oop_t arr;
int mode_set;
f = MOO_OOP_TO_SMOOI(fun); /* TODO: decode pointer properly */
arr = (moo_oop_oop_t)args;
dc = dcNewCallVM (4096);
if (!dc) return MOO_PF_HARD_FAILURE; /* TODO: proper error handling */
MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f);
/*dcMode (dc, DC_CALL_C_DEFAULT);
dcReset (dc);*/
/*for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++)
{
if (((moo_oop_char_t)sig)->slot[i] == '|')
{
dcMode (dc, DC_CALL_C_ELLIPSIS);
MOO_DEBUG0 (moo, "CALL MODE 111 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
mode_set = 1;
break;
}
}
if (!mode_set) */ dcMode (dc, DC_CALL_C_DEFAULT);
for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++)
{
MOO_DEBUG1 (moo, "FFI: CALLING ARG %c\n", ((moo_oop_char_t)sig)->slot[i]);
switch (((moo_oop_char_t)sig)->slot[i])
{
/* TODO: support more types... */
/*
case '|':
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS);
MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
break;
*/
case 'c':
/* TODO: sanity check on the argument type */
dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 2]));
break;
case 'i':
dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break;
case 'l':
dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break;
case 'L':
dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2]));
break;
case 's':
{
moo_oow_t bcslen, ucslen;
moo_bch_t bcs[1024];
ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 2]);
moo_convootobchars (moo, ((moo_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */
bcs[bcslen] = '\0';
dcArgPointer (dc, bcs);
break;
}
default:
/* TODO: ERROR HANDLING */
break;
}
}
MOO_STACK_POPS (moo, nargs);
switch (((moo_oop_char_t)sig)->slot[0])
{
/* TODO: support more types... */
/* TODO: proper return value conversion */
case 'c':
{
char r = dcCallChar (dc, f);
MOO_STACK_SETTOP (moo, MOO_CHAR_TO_OOP(r));
break;
}
case 'i':
{
int r = dcCallInt (dc, f);
MOO_DEBUG1 (moo, "CALLED... %d\n", r);
MOO_DEBUG2 (moo, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r));
break;
}
case 'l':
{
long r = dcCallLong (dc, f);
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r));
break;
}
case 'L':
{
long long r = dcCallLongLong (dc, f);
MOO_STACK_SETTOP (moo, MOO_SMOOI_TO_OOP(r));
break;
}
case 's':
{
moo_oow_t bcslen, ucslen;
moo_ooch_t ucs[1024];
moo_oop_t s;
char* r = dcCallPointer (dc, f);
bcslen = strlen(r);
moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* proper string conversion */
s = moo_makestring(moo, ucs, ucslen)
if (!s)
{
dcFree (dc);
return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */
}
MOO_STACK_SETTOP (moo, s);
break;
}
default:
/* TOOD: ERROR HANDLING */
break;
}
dcFree (dc);
}
return MOO_PF_SUCCESS;
#else
return MOO_PF_FAILURE;
#endif
}
static moo_pfrc_t pf_ffi_getsym (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, hnd, fun;
void* sym;
MOO_ASSERT (moo, nargs == 2);
rcv = MOO_STACK_GET(moo, moo->sp - 2);
fun = MOO_STACK_GET(moo, moo->sp - 1);
hnd = MOO_STACK_GET(moo, moo->sp);
if (!MOO_OOP_IS_SMOOI(hnd)) /* TODO: how to store pointer */
{
/* TODO: more info on error */
return MOO_PF_FAILURE;
}
if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR))
{
MOO_DEBUG0 (moo, "wrong function name...\n");
return MOO_PF_FAILURE;
}
if (!moo->vmprim.dl_getsym)
{
return MOO_PF_FAILURE;
}
sym = moo->vmprim.dl_getsym (moo, (void*)MOO_OOP_TO_SMOOI(hnd), ((moo_oop_char_t)fun)->slot);
if (!sym)
{
return MOO_PF_FAILURE;
}
/* TODO: how to hold an address? as an integer???? or a byte array? */
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(sym));
return MOO_PF_SUCCESS;
}
#endif