From 1612143499912580fdd6a09bc0b6085e6606b58f Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 10 Jan 2017 13:56:19 +0000 Subject: [PATCH] added MOO_IN_SMPTR_RANGE(), MOO_SMPTR_TO_OOP(), MOO_OOP_TO_SMPTR(). refactored ffi a bit more --- moo/kernel/FFI.moo | 12 +++++- moo/lib/bigint.c | 12 ++++++ moo/lib/exec.c | 4 +- moo/lib/main.c | 14 +++--- moo/lib/moo-prv.h | 5 --- moo/lib/moo.c | 2 +- moo/lib/moo.h | 28 ++++++++++-- moo/mod/console.c | 1 + moo/mod/ffi.c | 104 +++++++++++++++++++++++++++++++-------------- 9 files changed, 132 insertions(+), 50 deletions(-) diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo index c38d73e..67d2b28 100644 --- a/moo/kernel/FFI.moo +++ b/moo/kernel/FFI.moo @@ -1,5 +1,13 @@ class(#byte) _FFI(Module) from 'ffi' { + (* + * the ffi module installs the following methods + * method(#class) _newInstSize + * method open: name + * method close + * method call + * method call: func sig: sig with: args. + *) } class FFI(Object) @@ -43,6 +51,8 @@ class FFI(Object) (f isError) ifTrue: [^f]. self.funcs at: name put: f. ]. - ^self.ffi call: f sig: sig with: args + + (*^self.ffi call: f sig: sig with: args*) + ^self.ffi call(f, sig, args) } } diff --git a/moo/lib/bigint.c b/moo/lib/bigint.c index 641b5e1..44b5bfc 100644 --- a/moo/lib/bigint.c +++ b/moo/lib/bigint.c @@ -488,6 +488,18 @@ moo_oop_t moo_oowtoint (moo_t* moo, moo_oow_t w) } } +moo_oop_t moo_ooitoint (moo_t* moo, moo_ooi_t i) +{ + if (MOO_IN_SMOOI_RANGE(i)) + { + return MOO_SMOOI_TO_OOP(i); + } + else + { + return make_bigint_with_ooi (moo, i); + } +} + static MOO_INLINE moo_oop_t expand_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t inc) { moo_oop_t z; diff --git a/moo/lib/exec.c b/moo/lib/exec.c index b165937..afdb657 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1337,7 +1337,7 @@ static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs) switch (MOO_OOP_GET_TAG(rcv)) { - case MOO_OOP_TAG_SMINT: + case MOO_OOP_TAG_SMOOI: return MOO_OOP_TO_SMOOI(rcv) == MOO_OOP_TO_SMOOI(arg)? 1: 0; case MOO_OOP_TAG_CHAR: @@ -1700,7 +1700,7 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs) switch (MOO_OOP_GET_TAG(rcv)) { - case MOO_OOP_TAG_SMINT: + case MOO_OOP_TAG_SMOOI: hv = MOO_OOP_TO_SMOOI(rcv); break; diff --git a/moo/lib/main.c b/moo/lib/main.c index 0b3194b..c9511ca 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -325,15 +325,19 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags) /* 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) + + if (moo_findbchar (buf, bcslen, '.')) { - 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); + else + { + handle = lt_dlopenext (buf); + if (!handle) MOO_DEBUG2 (moo, "Failed to open(ext) DL %hs - %s\n", buf, lt_dlerror()); + else MOO_DEBUG2 (moo, "Opened(ext) DL %hs handle %p\n", buf, handle); + } } return handle; @@ -755,7 +759,7 @@ int main (int argc, char* argv[]) } } - printf ("COMPILE OK. STARTING EXECUTION ...\n"); + MOO_DEBUG0 (moo, "COMPILE OK. STARTING EXECUTION...\n"); xret = 0; g_moo = moo; setup_tick (); diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 454db5b..1a36aec 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1009,11 +1009,6 @@ int moo_inttooow ( moo_oow_t* w ); -moo_oop_t moo_oowtoint ( - moo_t* moo, - moo_oow_t w -); - moo_oop_t moo_addints ( moo_t* moo, moo_oop_t x, diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 1ae272f..1669ac2 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -110,7 +110,7 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t fill_bigint_tables (moo); - moo->tagged_classes[MOO_OOP_TAG_SMINT] = &moo->_small_integer; + moo->tagged_classes[MOO_OOP_TAG_SMOOI] = &moo->_small_integer; moo->tagged_classes[MOO_OOP_TAG_CHAR] = &moo->_character; moo->tagged_classes[MOO_OOP_TAG_ERROR] = &moo->_error_class; diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 9b8c677..9ed0225 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -196,7 +196,7 @@ typedef enum moo_method_type_t moo_method_type_t; */ #define MOO_OOP_TAG_BITS 2 -#define MOO_OOP_TAG_SMINT 1 +#define MOO_OOP_TAG_SMOOI 1 #define MOO_OOP_TAG_CHAR 2 #define MOO_OOP_TAG_ERROR 3 @@ -204,11 +204,11 @@ typedef enum moo_method_type_t moo_method_type_t; #define MOO_OOP_IS_NUMERIC(oop) (MOO_OOP_GET_TAG(oop) != 0) #define MOO_OOP_IS_POINTER(oop) (MOO_OOP_GET_TAG(oop) == 0) -#define MOO_OOP_IS_SMOOI(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_SMINT) +#define MOO_OOP_IS_SMOOI(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_SMOOI) #define MOO_OOP_IS_CHAR(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_CHAR) #define MOO_OOP_IS_ERROR(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_ERROR) -#define MOO_SMOOI_TO_OOP(num) ((moo_oop_t)((((moo_ooi_t)(num)) << MOO_OOP_TAG_BITS) | MOO_OOP_TAG_SMINT)) +#define MOO_SMOOI_TO_OOP(num) ((moo_oop_t)((((moo_ooi_t)(num)) << MOO_OOP_TAG_BITS) | MOO_OOP_TAG_SMOOI)) #define MOO_OOP_TO_SMOOI(oop) (((moo_ooi_t)oop) >> MOO_OOP_TAG_BITS) #define MOO_CHAR_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(num)) << MOO_OOP_TAG_BITS) | MOO_OOP_TAG_CHAR)) #define MOO_OOP_TO_CHAR(oop) (((moo_oow_t)oop) >> MOO_OOP_TAG_BITS) @@ -227,6 +227,17 @@ typedef enum moo_method_type_t moo_method_type_t; #define MOO_SMOOI_MIN (-MOO_SMOOI_MAX) #define MOO_IN_SMOOI_RANGE(ooi) ((ooi) >= MOO_SMOOI_MIN && (ooi) <= MOO_SMOOI_MAX) + +/* SMPTR is a special SMOOI value which has been devised to + * encode an address value whose low MOO_OOP_TAG_BITS bits are 0. + * its class is still SmallInteger. A pointer returned by most of + * system functions would be aligned to the pointer size. + * you can use tthe followings macros when storing such a pointer + * in a small integer without loss. */ +#define MOO_IN_SMPTR_RANGE(ptr) ((((moo_oow_t)ptr) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS)) == 0) +#define MOO_SMPTR_TO_OOP(ptr) ((moo_oop_t)(((moo_oow_t)ptr) | MOO_OOP_TAG_SMOOI)) +#define MOO_OOP_TO_SMPTR(oop) ((void*)(((moo_oow_t)oop) & ~MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS))) + /* TODO: There are untested code where a small integer is converted to moo_oow_t. * for example, the spec making macro treats the number as moo_oow_t instead of moo_ooi_t. * as of this writing, i skip testing that part with the spec value exceeding MOO_SMOOI_MAX. @@ -1298,6 +1309,17 @@ MOO_EXPORT moo_oop_t moo_makestring ( moo_oow_t len ); + +MOO_EXPORT moo_oop_t moo_oowtoint ( + moo_t* moo, + moo_oow_t w +); + +MOO_EXPORT moo_oop_t moo_ooitoint ( + moo_t* moo, + moo_ooi_t i +); + /* ========================================================================= * TEMPORARY OOP MANAGEMENT FUNCTIONS * ========================================================================= */ diff --git a/moo/mod/console.c b/moo/mod/console.c index 621f467..ac29095 100644 --- a/moo/mod/console.c +++ b/moo/mod/console.c @@ -28,6 +28,7 @@ #include "console.h" #include +#include #if defined(_WIN32) #elif defined(__DOS__) diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index 1843e4a..fa46ee1 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -33,10 +33,10 @@ #define HAVE_DYNCALL #if defined(HAVE_DYNCALL) -/* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ -# include /* TODO: remove this. make dyXXXX calls to callbacks */ +# include #endif +typedef void* ptr_t; typedef struct ffi_t ffi_t; struct ffi_t @@ -56,14 +56,18 @@ 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_oop_t name; - MOO_ASSERT (moo, nargs == 1); + if (nargs != 1) + { + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; + } rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); - arg = MOO_STACK_GETARG(moo, nargs, 0); + name = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo, arg, MOO_OBJ_TYPE_CHAR) || !MOO_OBJ_GET_FLAGS_EXTRA(arg)) /* TODO: better null check instead of FLAGS_EXTREA check */ + if (!MOO_ISTYPEOF(moo, name, MOO_OBJ_TYPE_CHAR) || !MOO_OBJ_GET_FLAGS_EXTRA(name)) /* TODO: better null check instead of FLAGS_EXTREA check */ { moo_seterrnum (moo, MOO_EINVAL); goto reterr; @@ -75,9 +79,10 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) goto reterr; } - rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)arg)->slot, 0); + rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)name)->slot, 0); if (!rcv->handle) goto reterr; + MOO_DEBUG3 (moo, " %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle); MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -95,22 +100,32 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) #if defined(HAVE_DYNCALL) ffi_t* rcv; - MOO_ASSERT (moo, nargs == 0); + if (nargs != 0) + { + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; + } rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); if (!moo->vmprim.dl_open) { moo_seterrnum (moo, MOO_ENOIMPL); - return MOO_PF_SUCCESS; + goto reterr; } + MOO_DEBUG1 (moo, " %p\n", rcv->handle); + moo->vmprim.dl_close (moo, rcv->handle); rcv->handle = MOO_NULL; 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; @@ -153,7 +168,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) moo_oop_oop_t arr; int mode_set; - f = MOO_OOP_TO_SMOOI(fun); /* TODO: decode pointer properly */ + f = MOO_OOP_TO_SMPTR(fun); arr = (moo_oop_oop_t)args; dc = dcNewCallVM (4096); @@ -163,11 +178,12 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) goto reterr; } -MOO_DEBUG1 (moo, "FFI: CALLING............%p\n", f); + MOO_DEBUG2 (moo, " %p in %p\n", f, rcv->handle); + /*dcMode (dc, DC_CALL_C_DEFAULT); dcReset (dc);*/ - /*for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++) + /*for (i = 1; i < MOO_OBJ_GET_SIZE(sig); i++) { if (((moo_oop_char_t)sig)->slot[i] == '|') { @@ -179,7 +195,7 @@ MOO_DEBUG0 (moo, "CALL MODE 111 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP } if (!mode_set) */ dcMode (dc, DC_CALL_C_DEFAULT); - for (i = 2; i < MOO_OBJ_GET_SIZE(sig); i++) + for (i = 1; 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]) @@ -194,19 +210,22 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP case 'c': /* TODO: sanity check on the argument type */ - dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 2])); + dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 1])); break; case 'i': - dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); +/* TODO: use moo_inttoooi () */ + dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 1])); break; case 'l': - dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); +/* TODO: use moo_inttoooi () */ + dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 1])); break; case 'L': - dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 2])); +/* TODO: use moo_inttoooi () */ + dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 1])); break; #if 0 @@ -217,7 +236,7 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP moo_oow_t bcslen, ucslen; moo_bch_t bcs[1024]; - ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 2]); + ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 1]); moo_convootobchars (moo, ((moo_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */ bcs[bcslen] = '\0'; @@ -245,26 +264,39 @@ MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPP 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_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(r)); + moo_oop_t r; + r = moo_ooitoint (moo, dcCallInt (dc, f)); + if (!r) return MOO_PF_HARD_FAILURE; + MOO_STACK_SETRET (moo, nargs, r); break; } case 'l': { - long r = dcCallLong (dc, f); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(r)); + moo_oop_t r; + r = moo_ooitoint (moo, dcCallLong (dc, f)); + if (!r) return MOO_PF_HARD_FAILURE; + MOO_STACK_SETRET (moo, nargs, r); break; } + #if (STIX_SIZEOF_LONG_LONG > 0) case 'L': { long long r = dcCallLongLong (dc, f); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(r)); + mod_oop_t r; + + #if STIX_SIZEOF_LONG_LONG <= STIX_SIZEOF_LONG + r = moo_ooitoint (moo, dcCallLongLong (dc, f)); + #else + # error TODO:... + #endif + if (!rr) return MOD_PF_HARD_FAILURE; + + MOO_STACK_SETRET (moo, nargs, r); break; } + #endif #if 0 case 'b': /* byte array */ @@ -319,15 +351,19 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs) { #if defined(HAVE_DYNCALL) ffi_t* rcv; - moo_oop_t fun; + moo_oop_t name; void* sym; - MOO_ASSERT (moo, nargs == 1); + if (nargs != 1) + { + moo_seterrnum (moo, MOO_EINVAL); + goto reterr; + } rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); - fun = MOO_STACK_GETARG(moo, nargs, 0); + name = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo,fun,MOO_OBJ_TYPE_CHAR)) + if (!MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR)) /* TODO: null check on the symbol name? */ { moo_seterrnum (moo, MOO_EINVAL); goto reterr; @@ -339,11 +375,13 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs) goto reterr; } - sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)fun)->slot); + sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)name)->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((moo_oow_t)sym)); + MOO_DEBUG4 (moo, " %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, rcv->handle); + + MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(sym)); + MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(sym)); return MOO_PF_SUCCESS; reterr: @@ -427,7 +465,7 @@ static moo_pfimpl_t query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) static void unload (moo_t* moo, moo_mod_t* mod) { - /* TODO: close all open libraries...?? */ + /* TODO: anything? close open open dll handles? For that, pf_open must store the value it returns to mod->ctx or somewhere..*/ } int moo_mod_ffi (moo_t* moo, moo_mod_t* mod)