added moo_duputobcharswithheadroom(), moo_dupbtoucharswithheadroom()

added moo_inttoooi() and made public moo_inttooow()
enhanced the ffi module a bit more
This commit is contained in:
hyunghwan.chung 2017-01-15 17:53:37 +00:00
parent 79198df35b
commit 70f9976af3
12 changed files with 299 additions and 110 deletions

View File

@ -338,6 +338,18 @@ int moo_inttooow (moo_t* moo, moo_oop_t x, moo_oow_t* w)
return 0; /* not convertable - too big, too small, or not an integer */ return 0; /* not convertable - too big, too small, or not an integer */
} }
int moo_inttoooi (moo_t* moo, moo_oop_t x, moo_ooi_t* i)
{
moo_oow_t w;
int n;
n = moo_inttooow (moo, x, &w);
if (n < 0) *i = -w;
else if (n > 0) *i = w;
return n;
}
static MOO_INLINE moo_oop_t make_bigint_with_oow (moo_t* moo, moo_oow_t w) static MOO_INLINE moo_oop_t make_bigint_with_oow (moo_t* moo, moo_oow_t w)
{ {
#if (MOO_LIW_BITS == MOO_OOW_BITS) #if (MOO_LIW_BITS == MOO_OOW_BITS)

View File

@ -195,10 +195,16 @@ moo_errnum_t moo_syserrtoerrnum (int e)
{ {
case ENOMEM: return MOO_ESYSMEM; case ENOMEM: return MOO_ESYSMEM;
case EINVAL: return MOO_EINVAL; case EINVAL: return MOO_EINVAL;
#if defined(EBUSY)
case EBUSY: return MOO_EBUSY; case EBUSY: return MOO_EBUSY;
#endif
case EACCES: return MOO_EACCES; case EACCES: return MOO_EACCES;
#if defined(EPERM)
case EPERM: return MOO_EPERM; case EPERM: return MOO_EPERM;
#endif
#if defined(ENOTDIR)
case ENOTDIR: return MOO_ENOTDIR; case ENOTDIR: return MOO_ENOTDIR;
#endif
case ENOENT: return MOO_ENOENT; case ENOENT: return MOO_ENOENT;
#if defined(EEXIST) #if defined(EEXIST)
case EEXIST: return MOO_EEXIST; case EEXIST: return MOO_EEXIST;

View File

@ -122,7 +122,7 @@
# define LOG_INST_3(moo,fmt,a1,a2,a3) # define LOG_INST_3(moo,fmt,a1,a2,a3)
#endif #endif
#if defined(__DOS__) && defined(_INTELC32_) #if defined(__DOS__) && (defined(_INTELC32_) || (defined(__WATCOMC__) && (__WATCOMC__ <= 1000)))
/* the old intel c code builder doesn't support __FUNCTION__ */ /* the old intel c code builder doesn't support __FUNCTION__ */
# define __PRIMITIVE_NAME__ "<<primitive>>" # define __PRIMITIVE_NAME__ "<<primitive>>"
#else #else
@ -145,13 +145,15 @@ static MOO_INLINE void vm_gettime (moo_t* moo, moo_ntime_t* now)
/* it must return NO_ERROR */ /* it must return NO_ERROR */
MOO_INITNTIME (now, MOO_MSEC_TO_SEC(out), MOO_MSEC_TO_NSEC(out)); MOO_INITNTIME (now, MOO_MSEC_TO_SEC(out), MOO_MSEC_TO_NSEC(out));
#elif defined(__DOS__) && defined(_INTELC32_) #elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
clock_t c; clock_t c;
/* TODO: handle overflow?? */ /* TODO: handle overflow?? */
c = clock (); c = clock ();
now->sec = c / CLOCKS_PER_SEC; now->sec = c / CLOCKS_PER_SEC;
#if (CLOCKS_PER_SEC == 1000) #if (CLOCKS_PER_SEC == 100)
now->nsec = MOO_MSEC_TO_NSEC((c % CLOCKS_PER_SEC) * 10);
#elif (CLOCKS_PER_SEC == 1000)
now->nsec = MOO_MSEC_TO_NSEC(c % CLOCKS_PER_SEC); now->nsec = MOO_MSEC_TO_NSEC(c % CLOCKS_PER_SEC);
#elif (CLOCKS_PER_SEC == 1000000L) #elif (CLOCKS_PER_SEC == 1000000L)
now->nsec = MOO_USEC_TO_NSEC(c % CLOCKS_PER_SEC); now->nsec = MOO_USEC_TO_NSEC(c % CLOCKS_PER_SEC);
@ -218,13 +220,16 @@ static MOO_INLINE void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
/* TODO: ... */ /* TODO: ... */
#elif defined(__DOS__) && defined(_INTELC32_) #elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
clock_t c; clock_t c;
c = clock (); c = clock ();
c += dur->sec * CLOCKS_PER_SEC; c += dur->sec * CLOCKS_PER_SEC;
#if (CLOCKS_PER_SEC == 1000)
#if (CLOCKS_PER_SEC == 100)
c += MOO_NSEC_TO_MSEC(dur->nsec) / 10;
#elif (CLOCKS_PER_SEC == 1000)
c += MOO_NSEC_TO_MSEC(dur->nsec); c += MOO_NSEC_TO_MSEC(dur->nsec);
#elif (CLOCKS_PER_SEC == 1000000L) #elif (CLOCKS_PER_SEC == 1000000L)
c += MOO_NSEC_TO_USEC(dur->nsec); c += MOO_NSEC_TO_USEC(dur->nsec);

View File

@ -48,6 +48,7 @@
#elif defined(__DOS__) #elif defined(__DOS__)
# include <dos.h> # include <dos.h>
# include <time.h> # include <time.h>
# include <io.h>
#elif defined(macintosh) #elif defined(macintosh)
# include <Timer.h> # include <Timer.h>
#else #else
@ -510,11 +511,20 @@ static moo_t* g_moo = MOO_NULL;
/* ========================================================================= */ /* ========================================================================= */
#if defined(__DOS__) && defined(_INTELC32_) #if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
static void (*prev_timer_intr_handler) (void);
#if defined(_INTELC32_)
static void (*prev_timer_intr_handler) (void);
#else
static void (__interrupt *prev_timer_intr_handler) (void);
#endif
#if defined(_INTELC32_)
#pragma interrupt(timer_intr_handler) #pragma interrupt(timer_intr_handler)
static void timer_intr_handler (void) static void timer_intr_handler (void)
#else
static void __interrupt timer_intr_handler (void)
#endif
{ {
/* /*
_XSTACK *stk; _XSTACK *stk;
@ -551,7 +561,7 @@ static void arrange_process_switching (int sig)
static void setup_tick (void) static void setup_tick (void)
{ {
#if defined(__DOS__) && defined(_INTELC32_) #if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
prev_timer_intr_handler = _dos_getvect (0x1C); prev_timer_intr_handler = _dos_getvect (0x1C);
_dos_setvect (0x1C, timer_intr_handler); _dos_setvect (0x1C, timer_intr_handler);
@ -587,7 +597,7 @@ static void setup_tick (void)
static void cancel_tick (void) static void cancel_tick (void)
{ {
#if defined(__DOS__) && defined(_INTELC32_) #if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__))
_dos_setvect (0x1C, prev_timer_intr_handler); _dos_setvect (0x1C, prev_timer_intr_handler);

View File

@ -561,7 +561,7 @@ typedef struct moo_t moo_t;
# define MOO_IMPORT # define MOO_IMPORT
# define MOO_EXPORT # define MOO_EXPORT
# define MOO_PRIVATE # define MOO_PRIVATE
#elif defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__)) #elif defined(_WIN32) || (defined(__WATCOMC__) && (__WATCOMC__ >= 1000) && !defined(__WINDOWS_386__))
# define MOO_IMPORT __declspec(dllimport) # define MOO_IMPORT __declspec(dllimport)
# define MOO_EXPORT __declspec(dllexport) # define MOO_EXPORT __declspec(dllexport)
# define MOO_PRIVATE # define MOO_PRIVATE

View File

@ -47,7 +47,11 @@
# define MOO_SIZEOF___INT8 1 # define MOO_SIZEOF___INT8 1
# define MOO_SIZEOF___INT16 2 # define MOO_SIZEOF___INT16 2
# define MOO_SIZEOF___INT32 4 # define MOO_SIZEOF___INT32 4
# if (__WATCOMC__ < 1000)
# define MOO_SIZEOF___INT64 0
# else
# define MOO_SIZEOF___INT64 8 # define MOO_SIZEOF___INT64 8
# endif
# define MOO_SIZEOF___INT128 0 # define MOO_SIZEOF___INT128 0
# define MOO_SIZEOF_OFF64_T 0 # define MOO_SIZEOF_OFF64_T 0

View File

@ -1003,12 +1003,6 @@ int moo_isint (
moo_oop_t x moo_oop_t x
); );
int moo_inttooow (
moo_t* moo,
moo_oop_t x,
moo_oow_t* w
);
moo_oop_t moo_addints ( moo_oop_t moo_addints (
moo_t* moo, moo_t* moo,
moo_oop_t x, moo_oop_t x,

View File

@ -1311,12 +1311,23 @@ MOO_EXPORT moo_oop_t moo_makesymbol (
moo_oow_t len moo_oow_t len
); );
MOO_EXPORT moo_oop_t moo_makestring ( MOO_EXPORT moo_oop_t moo_makestringwithuchars (
moo_t* moo, moo_t* moo,
const moo_ooch_t* ptr, const moo_uch_t* ptr,
moo_oow_t len moo_oow_t len
); );
MOO_EXPORT moo_oop_t moo_makestringwithbchars (
moo_t* moo,
const moo_bch_t* ptr,
moo_oow_t len
);
#if defined(MOO_OOCH_IS_UCH)
# define moo_makestring(moo,ptr,len) moo_makestringwithuchars(moo,ptr,len)
#else
# define moo_makestring(moo,ptr,len) moo_makestringwithbchars(moo,ptr,len)
#endif
MOO_EXPORT moo_oop_t moo_oowtoint ( MOO_EXPORT moo_oop_t moo_oowtoint (
moo_t* moo, moo_t* moo,
@ -1328,6 +1339,19 @@ MOO_EXPORT moo_oop_t moo_ooitoint (
moo_ooi_t i moo_ooi_t i
); );
MOO_EXPORT int moo_inttooow (
moo_t* moo,
moo_oop_t x,
moo_oow_t* w
);
MOO_EXPORT int moo_inttoooi (
moo_t* moo,
moo_oop_t x,
moo_ooi_t* i
);
/* ========================================================================= /* =========================================================================
* TEMPORARY OOP MANAGEMENT FUNCTIONS * TEMPORARY OOP MANAGEMENT FUNCTIONS
* ========================================================================= */ * ========================================================================= */
@ -1443,11 +1467,15 @@ int moo_convutobcstr (
#if defined(MOO_OOCH_IS_UCH) #if defined(MOO_OOCH_IS_UCH)
# define moo_dupootobcharswithheadroom(moo,hrb,oocs,oocslen,bcslen) moo_duputobcharswithheadroom(moo,hrb,oocs,oocslen,bcslen)
# define moo_dupbtooocharswithheadroom(moo,hrb,bcs,bcslen,oocslen) moo_dupbtoucharswithheadroom(moo,hrb,bcs,bcslen,oocslen)
# define moo_dupootobchars(moo,oocs,oocslen,bcslen) moo_duputobchars(moo,oocs,oocslen,bcslen) # define moo_dupootobchars(moo,oocs,oocslen,bcslen) moo_duputobchars(moo,oocs,oocslen,bcslen)
# define moo_dupbtooochars(moo,bcs,bcslen,oocslen) moo_dupbtouchars(moo,bcs,bcslen,oocslen) # define moo_dupbtooochars(moo,bcs,bcslen,oocslen) moo_dupbtouchars(moo,bcs,bcslen,oocslen)
# define moo_dupootobcstr(moo,oocs,bcslen) moo_duputobcstr(moo,oocs,bcslen) # define moo_dupootobcstr(moo,oocs,bcslen) moo_duputobcstr(moo,oocs,bcslen)
# define moo_dupbtooocstr(moo,bcs,oocslen) moo_dupbtoucstr(moo,bcs,oocslen) # define moo_dupbtooocstr(moo,bcs,oocslen) moo_dupbtoucstr(moo,bcs,oocslen)
#else #else
# define moo_dupootoucharswithheadroom(moo,hrb,oocs,oocslen,ucslen) moo_dupbtoucharswithheadroom(moo,hrb,oocs,oocslen,ucslen)
# define moo_duputooocharswithheadroom(moo,hrb,ucs,ucslen,oocslen) moo_duputobcharswithheadroom(moo,hrb,ucs,ucslen,oocslen)
# define moo_dupootouchars(moo,oocs,oocslen,ucslen) moo_dupbtouchars(moo,oocs,oocslen,ucslen) # define moo_dupootouchars(moo,oocs,oocslen,ucslen) moo_dupbtouchars(moo,oocs,oocslen,ucslen)
# define moo_duputooochars(moo,ucs,ucslen,oocslen) moo_duputobchars(moo,ucs,ucslen,oocslen) # define moo_duputooochars(moo,ucs,ucslen,oocslen) moo_duputobchars(moo,ucs,ucslen,oocslen)
# define moo_dupootoucstr(moo,oocs,ucslen) moo_dupbtoucstr(moo,oocs,ucslen) # define moo_dupootoucstr(moo,oocs,ucslen) moo_dupbtoucstr(moo,oocs,ucslen)
@ -1455,6 +1483,22 @@ int moo_convutobcstr (
#endif #endif
MOO_EXPORT moo_uch_t* moo_dupbtoucharswithheadroom (
moo_t* moo,
moo_oow_t headroom_bytes,
const moo_bch_t* bcs,
moo_oow_t bcslen,
moo_oow_t* ucslen
);
MOO_EXPORT moo_bch_t* moo_duputobcharswithheadroom (
moo_t* moo,
moo_oow_t headroom_bytes,
const moo_uch_t* ucs,
moo_oow_t ucslen,
moo_oow_t* bcslen
);
MOO_EXPORT moo_uch_t* moo_dupbtouchars ( MOO_EXPORT moo_uch_t* moo_dupbtouchars (
moo_t* moo, moo_t* moo,
const moo_bch_t* bcs, const moo_bch_t* bcs,

View File

@ -142,7 +142,7 @@ static MOO_INLINE moo_oop_t alloc_numeric_array (moo_t* moo, const void* ptr, mo
} }
else else
{ {
/* initialize with zeros when the string pointer is not given */ /* initialize with zeros when the data pointer is NULL */
MOO_MEMSET ((hdr + 1), 0, nbytes_aligned); MOO_MEMSET ((hdr + 1), 0, nbytes_aligned);
} }

View File

@ -180,7 +180,40 @@ moo_oop_t moo_findsymbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len)
return find_or_make_symbol (moo, ptr, len, 0); return find_or_make_symbol (moo, ptr, len, 0);
} }
moo_oop_t moo_makestring (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len) moo_oop_t moo_makestringwithbchars (moo_t* moo, const moo_bch_t* ptr, moo_oow_t len)
{ {
#if defined(MOO_OOCH_IS_UCH)
moo_oow_t inlen, outlen;
moo_oop_t obj;
inlen = len;
if (moo_convbtouchars (moo, ptr, &inlen, MOO_NULL, &outlen) <= -1) return MOO_NULL;
obj = moo_instantiate (moo, moo->_string, MOO_NULL, outlen);
if (!obj) return MOO_NULL;
inlen = len;
moo_convbtouchars (moo, ptr, &inlen, MOO_OBJ_GET_CHAR_SLOT(obj), &outlen);
return obj;
#else
return moo_instantiate (moo, moo->_string, ptr, len); return moo_instantiate (moo, moo->_string, ptr, len);
#endif
}
moo_oop_t moo_makestringwithuchars (moo_t* moo, const moo_uch_t* ptr, moo_oow_t len)
{
#if defined(MOO_OOCH_IS_UCH)
return moo_instantiate (moo, moo->_string, ptr, len);
#else
moo_oow_t inlen, outlen;
moo_oop_t obj;
inlen = len;
if (moo_convutobchars (moo, ptr, &inlen, MOO_NULL, &outlen) <= -1) return MOO_NULL;
obj = moo_instantiate (moo, moo->_string, MOO_NULL, outlen);
if (!obj) return MOO_NULL;
inlen = len;
moo_convutobchars (moo, ptr, &inlen, MOO_OBJ_GET_CHAR_SLOT(obj), &outlen);
return obj;
#endif
} }

View File

@ -670,7 +670,7 @@ int moo_convutobcstr (moo_t* moo, const moo_uch_t* ucs, moo_oow_t* ucslen, moo_b
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
moo_uch_t* moo_dupbtouchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t bcslen, moo_oow_t* ucslen) MOO_INLINE moo_uch_t* moo_dupbtoucharswithheadroom (moo_t* moo, moo_oow_t headroom_bytes, const moo_bch_t* bcs, moo_oow_t bcslen, moo_oow_t* ucslen)
{ {
moo_oow_t inlen, outlen; moo_oow_t inlen, outlen;
moo_uch_t* ptr; moo_uch_t* ptr;
@ -682,10 +682,12 @@ moo_uch_t* moo_dupbtouchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t bcslen,
return MOO_NULL; return MOO_NULL;
} }
ptr = moo_allocmem (moo, (outlen + 1) * MOO_SIZEOF(moo_uch_t)); ptr = moo_allocmem (moo, headroom_bytes + ((outlen + 1) * MOO_SIZEOF(moo_uch_t)));
if (!ptr) return MOO_NULL; if (!ptr) return MOO_NULL;
inlen = bcslen; inlen = bcslen;
ptr = (moo_uch_t*)((moo_oob_t*)ptr + headroom_bytes);
moo_convbtouchars (moo, bcs, &inlen, ptr, &outlen); moo_convbtouchars (moo, bcs, &inlen, ptr, &outlen);
/* moo_convbtouchars() doesn't null-terminate the target. /* moo_convbtouchars() doesn't null-terminate the target.
@ -696,7 +698,12 @@ moo_uch_t* moo_dupbtouchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t bcslen,
return ptr; return ptr;
} }
moo_bch_t* moo_duputobchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen, moo_oow_t* bcslen) moo_uch_t* moo_dupbtouchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t bcslen, moo_oow_t* ucslen)
{
return moo_dupbtoucharswithheadroom (moo, 0, bcs, bcslen, ucslen);
}
MOO_INLINE moo_bch_t* moo_duputobcharswithheadroom (moo_t* moo, moo_oow_t headroom_bytes, const moo_uch_t* ucs, moo_oow_t ucslen, moo_oow_t* bcslen)
{ {
moo_oow_t inlen, outlen; moo_oow_t inlen, outlen;
moo_bch_t* ptr; moo_bch_t* ptr;
@ -708,10 +715,11 @@ moo_bch_t* moo_duputobchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen,
return MOO_NULL; return MOO_NULL;
} }
ptr = moo_allocmem (moo, (outlen + 1) * MOO_SIZEOF(moo_bch_t)); ptr = moo_allocmem (moo, headroom_bytes + ((outlen + 1) * MOO_SIZEOF(moo_bch_t)));
if (!ptr) return MOO_NULL; if (!ptr) return MOO_NULL;
inlen = ucslen; inlen = ucslen;
ptr = (moo_bch_t*)((moo_oob_t*)ptr + headroom_bytes);
moo_convutobchars (moo, ucs, &inlen, ptr, &outlen); moo_convutobchars (moo, ucs, &inlen, ptr, &outlen);
ptr[outlen] = '\0'; ptr[outlen] = '\0';
@ -719,6 +727,11 @@ moo_bch_t* moo_duputobchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen,
return ptr; return ptr;
} }
moo_bch_t* moo_duputobchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen, moo_oow_t* bcslen)
{
return moo_duputobcharswithheadroom (moo, 0, ucs, ucslen, bcslen);
}
moo_uch_t* moo_dupbtoucstr (moo_t* moo, const moo_bch_t* bcs, moo_oow_t* ucslen) moo_uch_t* moo_dupbtoucstr (moo_t* moo, const moo_bch_t* bcs, moo_oow_t* ucslen)
{ {
moo_oow_t inlen, outlen; moo_oow_t inlen, outlen;
@ -759,7 +772,6 @@ moo_bch_t* moo_duputobcstr (moo_t* moo, const moo_uch_t* ucs, moo_oow_t* bcslen)
return ptr; return ptr;
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
moo_uch_t* moo_dupuchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen) moo_uch_t* moo_dupuchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen)

View File

@ -38,15 +38,43 @@
# include <dyncall.h> # include <dyncall.h>
#endif #endif
typedef void* ptr_t; typedef struct link_t link_t;
struct link_t
{
link_t* next;
};
typedef struct ffi_t ffi_t; typedef struct ffi_t ffi_t;
struct ffi_t struct ffi_t
{ {
MOO_OBJ_HEADER; MOO_OBJ_HEADER;
void* handle; void* handle;
#if defined(USE_DYNCALL)
DCCallVM* dc;
#endif
link_t* ca; /* call arguments duplicated */
}; };
static MOO_INLINE void link_ca (ffi_t* ffi, void* ptr)
{
link_t* l = (link_t*)((moo_oob_t*)ptr - MOO_SIZEOF_VOID_P);
l->next = ffi->ca;
ffi->ca = l;
}
static void free_linked_cas (moo_t* moo, ffi_t* ffi)
{
while (ffi->ca)
{
link_t* ptr;
ptr = ffi->ca;
ffi->ca = ptr->next;
moo_freemem (moo, ptr);
}
}
static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs) 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_ooi_t newinstsize = MOO_SIZEOF(ffi_t) - MOO_SIZEOF(moo_obj_t);
@ -58,6 +86,10 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
{ {
ffi_t* rcv; ffi_t* rcv;
moo_oop_t name; moo_oop_t name;
void* handle;
#if defined(USE_DYNCALL)
DCCallVM* dc;
#endif
if (nargs != 1) if (nargs != 1)
{ {
@ -80,8 +112,27 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
goto softfail; goto softfail;
} }
rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)name)->slot, 0); if (rcv->handle)
if (!rcv->handle) goto softfail; {
moo_seterrnum (moo, MOO_EPERM); /* no allowed to open again */
goto softfail;
}
handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)name)->slot, 0);
if (!handle) goto softfail;
#if defined(USE_DYNCALL)
dc = dcNewCallVM (4096); /* TODO: right size? */
if (!dc)
{
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
moo->vmprim.dl_close (moo, handle);
goto softfail;
}
#endif
rcv->handle = handle;
rcv->dc = dc;
MOO_DEBUG3 (moo, "<ffi.open> %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle); MOO_DEBUG3 (moo, "<ffi.open> %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle);
MOO_STACK_SETRETTORCV (moo, nargs); MOO_STACK_SETRETTORCV (moo, nargs);
@ -112,6 +163,13 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
MOO_DEBUG1 (moo, "<ffi.close> %p\n", rcv->handle); MOO_DEBUG1 (moo, "<ffi.close> %p\n", rcv->handle);
free_linked_cas (moo, rcv);
#if defined(USE_DYNCALL)
dcFree (rcv->dc);
rcv->dc = MOO_NULL;
#endif
moo->vmprim.dl_close (moo, rcv->handle); moo->vmprim.dl_close (moo, rcv->handle);
rcv->handle = MOO_NULL; rcv->handle = MOO_NULL;
@ -128,15 +186,14 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
#if defined(USE_DYNCALL) #if defined(USE_DYNCALL)
ffi_t* rcv; ffi_t* rcv;
moo_oop_t fun, sig, args; moo_oop_t fun, sig, args;
DCCallVM* dc = MOO_NULL;
moo_oow_t i, j; moo_oow_t i, j;
void* f; void* f;
moo_oop_oop_t arr; moo_oop_oop_t arr;
int ellipsis = 0; int ellipsis = 0;
if (nargs < 3) goto inval;
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
if (nargs < 3) goto inval;
fun = MOO_STACK_GETARG(moo, nargs, 0); fun = MOO_STACK_GETARG(moo, nargs, 0);
sig = MOO_STACK_GETARG(moo, nargs, 1); sig = MOO_STACK_GETARG(moo, nargs, 1);
args = MOO_STACK_GETARG(moo, nargs, 2); args = MOO_STACK_GETARG(moo, nargs, 2);
@ -151,26 +208,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
f = MOO_OOP_TO_SMPTR(fun); f = MOO_OOP_TO_SMPTR(fun);
arr = (moo_oop_oop_t)args; arr = (moo_oop_oop_t)args;
dc = dcNewCallVM (4096); /* TODO: right size? */
if (!dc)
{
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
goto softfail;
}
MOO_DEBUG2 (moo, "<ffi.call> %p in %p\n", f, rcv->handle); MOO_DEBUG2 (moo, "<ffi.call> %p in %p\n", f, rcv->handle);
dcMode (dc, DC_CALL_C_DEFAULT); dcMode (rcv->dc, DC_CALL_C_DEFAULT);
dcReset (dc); dcReset (rcv->dc);
i = 0; i = 0;
if (i < MOO_OBJ_GET_SIZE(sig) && ((moo_oop_char_t)sig)->slot[i] == '|') if (i < MOO_OBJ_GET_SIZE(sig) && ((moo_oop_char_t)sig)->slot[i] == '|')
{ {
dcMode (dc, DC_CALL_C_ELLIPSIS); dcMode (rcv->dc, DC_CALL_C_ELLIPSIS);
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */ /* the error code should be DC_ERROR_UNSUPPORTED_MODE */
if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl; if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl;
dcReset (dc); dcReset (rcv->dc);
ellipsis = 1; ellipsis = 1;
i++; i++;
} }
@ -191,10 +241,10 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{ {
if (ellipsis) if (ellipsis)
{ {
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS); dcMode (rcv->dc, DC_CALL_C_ELLIPSIS_VARARGS);
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */ /* the error code should be DC_ERROR_UNSUPPORTED_MODE */
if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl; if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl;
} }
continue; continue;
} }
@ -207,31 +257,49 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{ {
/* TODO: support more types... */ /* TODO: support more types... */
case 'c': case 'c':
if (!MOO_OOP_IS_CHAR(arg)) goto inval; if (!MOO_OOP_IS_CHAR(arg)) goto inval;
dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[j])); dcArgChar (rcv->dc, MOO_OOP_TO_CHAR(arr->slot[j]));
j++; j++;
break; break;
/* TODO: added unsigned types */
case 'i': case 'i':
/* TODO: use moo_inttoooi () */ {
if (!MOO_OOP_IS_SMOOI(arg)) goto inval; moo_ooi_t v;
dcArgInt (dc, MOO_OOP_TO_SMOOI(arg)); if (moo_inttoooi(moo, arg, &v) == 0) goto inval;
dcArgInt (rcv->dc, i);
j++; j++;
break; break;
}
case 'l': case 'l':
/* TODO: sanity check on the argument type - check if arr->slot[j] is SMOOI or bigint... */ {
/* TODO: use moo_inttoooi () */ moo_ooi_t v;
dcArgLong (dc, MOO_OOP_TO_SMOOI(arg)); arg_as_long:
if (moo_inttoooi(moo, arg, &v) == 0) goto inval;
dcArgLong (rcv->dc, v);
j++; j++;
break; break;
}
case 'L': case 'L':
/* TODO: use moo_inttoooi () */ {
dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arg)); #if (MOO_SIZEOF_LONG_LONG > 0)
# if (MOO_SIZEOF_LONG_LONG <= MOO_SIZEOF_OOI_T)
moo_ooi_t v;
if (moo_inttoooi(moo, arg, &v) == 0) goto inval;
# else
/* TODO: moo_intmax_t v;
if (moo_inttointmax (moo, arg, &v) == 0) goto inval; */
# error UNSUPPORTED MOO_SIZEOF_LONG_LONG.
# endif
dcArgLongLong (rcv->dc, v);
j++; j++;
break; break;
#else
goto arg_as_long;
#endif
}
#if 0 #if 0
case 'B': /* byte array */ case 'B': /* byte array */
@ -241,16 +309,18 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
moo_bch_t* ptr; moo_bch_t* ptr;
/* TOOD: check if arg is a string. */ /* TOOD: check if arg is a string. */
/* TODO: free all duplicated strings after call */
#if defined(MOO_OOCH_IS_UCH) #if defined(MOO_OOCH_IS_UCH)
ptr = moo_dupootobchars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL); ptr = moo_dupootobcharswithheadroom (moo, MOO_SIZEOF_VOID_P, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL);
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
link_ca (rcv, ptr);
#else #else
ptr = MOO_OBJ_GET_CHAR_SLOT(arg); ptr = MOO_OBJ_GET_CHAR_SLOT(arg);
/*ptr = moo_dupoochars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg));*/ /*ptr = moo_dupoochars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg));
if (!ptr) goto softfail;*/ /* out of system memory or conversion error - soft failure */
#endif #endif
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
dcArgPointer (dc, ptr); dcArgPointer (rcv->dc, ptr);
j++; j++;
break; break;
} }
@ -261,20 +331,22 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
#if defined(MOO_OOCH_IS_UCH) #if defined(MOO_OOCH_IS_UCH)
ptr = MOO_OBJ_GET_CHAR_SLOT(arg); ptr = MOO_OBJ_GET_CHAR_SLOT(arg);
/*ptr = moo_dupoochars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg));*/ /*ptr = moo_dupoochars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg));
if (!ptr) goto softfail; */ /* out of system memory or conversion error - soft failure */
#else #else
ptr = moo_dupootouchars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL); ptr = moo_dupootoucharswithheadroom (moo, MOO_SIZEOF_VOID_P, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL);
#endif
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */ if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
link_ca (rcv, ptr);
#endif
dcArgPointer (dc, ptr); dcArgPointer (rcv->dc, ptr);
j++; j++;
break; break;
} }
default: default:
/* TODO: ERROR HANDLING */ /* invalid argument signature specifier */
break; goto inval;
} }
} }
@ -288,7 +360,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
/* TODO: proper return value conversion */ /* TODO: proper return value conversion */
case 'c': case 'c':
{ {
char r = dcCallChar (dc, f); char r = dcCallChar (rcv->dc, f);
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r)); MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r));
break; break;
} }
@ -297,7 +369,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t r; moo_oop_t r;
r = moo_ooitoint (moo, dcCallInt (dc, f)); r = moo_ooitoint (moo, dcCallInt (rcv->dc, f));
if (!r) goto hardfail; if (!r) goto hardfail;
MOO_STACK_SETRET (moo, nargs, r); MOO_STACK_SETRET (moo, nargs, r);
break; break;
@ -306,29 +378,30 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
case 'l': case 'l':
{ {
moo_oop_t r; moo_oop_t r;
r = moo_ooitoint (moo, dcCallLong (dc, f)); ret_as_long:
r = moo_ooitoint (moo, dcCallLong (rcv->dc, f));
if (!r) goto hardfail; if (!r) goto hardfail;
MOO_STACK_SETRET (moo, nargs, r); MOO_STACK_SETRET (moo, nargs, r);
break; break;
} }
#if (STIX_SIZEOF_LONG_LONG > 0)
case 'L': case 'L':
{ {
long long r = dcCallLongLong (dc, f); #if (MOO_SIZEOF_LONG_LONG > 0)
mod_oop_t r; moo_oop_t r;
# if (MOO_SIZEOF_LONG_LONG <= MOO_SIZEOF_OOI_T)
#if STIX_SIZEOF_LONG_LONG <= STIX_SIZEOF_LONG r = moo_ooitoint (moo, dcCallLongLong (rcv->dc, f));
r = moo_ooitoint (moo, dcCallLongLong (dc, f));
# else # else
# error TODO:... # error UNSUPPORTED MOO_SIZEOF_LONG_LONG
# endif # endif
if (!rr) goto hardfail; if (!r) goto hardfail;
MOO_STACK_SETRET (moo, nargs, r); MOO_STACK_SETRET (moo, nargs, r);
break; break;
} #else
goto ret_as_long;
#endif #endif
}
#if 0 #if 0
case 'B': /* byte array */ case 'B': /* byte array */
@ -340,20 +413,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t s; moo_oop_t s;
moo_bch_t* r; moo_bch_t* r;
moo_ooch_t* ptr;
moo_oow_t len;
r = dcCallPointer (dc, f); r = dcCallPointer (rcv->dc, f);
#if defined(MOO_OOCH_IS_UCH) #if defined(MOO_OOCH_IS_UCH)
ptr = moo_dupbtooocstr (moo, r, &len); s = moo_makestringwithbchars (moo, r, moo_countbcstr(r));
if (!ptr) goto softfail; /* out of system memory or conversion error - still soft failure */
s = moo_makestring(moo, ptr, len);
moo_freemem (moo, ptr);
#else #else
s = moo_makestring(moo, r, moo_countbcstr(r)); s = moo_makestring(moo, r, moo_countbcstr(r));
#endif #endif
if (!s) goto hardfail; /* out of object memory - hard failure*/ if (!s)
{
if (moo->errnum == MOO_EOOMEM) goto hardfail; /* out of object memory - hard failure*/
goto softfail;
}
MOO_STACK_SETRET (moo, nargs, s); MOO_STACK_SETRET (moo, nargs, s);
break; break;
@ -363,20 +435,20 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t s; moo_oop_t s;
moo_uch_t* r; moo_uch_t* r;
moo_ooch_t* ptr;
moo_oow_t len;
r = dcCallPointer (dc, f);
r = dcCallPointer (rcv->dc, f);
#if defined(MOO_OOCH_IS_UCH) #if defined(MOO_OOCH_IS_UCH)
s = moo_makestring(moo, r, moo_countucstr(r)); s = moo_makestring(moo, r, moo_countucstr(r));
#else #else
ptr = moo_dupbtooocstr (moo, r, &len); s = moo_makestringwithuchars(moo, r, moo_countucstr(r));
if (!ptr) goto softfail; /* out of system memory or conversion error - still soft failure */
s = moo_makestring(moo, ptr, len);
moo_freemem (moo, ptr);
#endif #endif
if (!s) goto hardfail; /* out of object memory - hard failure*/ if (!s)
{
if (moo->errnum == MOO_EOOMEM) goto hardfail; /* out of object memory - hard failure*/
goto softfail;
}
MOO_STACK_SETRET (moo, nargs, s); MOO_STACK_SETRET (moo, nargs, s);
break; break;
@ -384,13 +456,12 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
default: default:
call_void: call_void:
dcCallVoid (dc, f); dcCallVoid (rcv->dc, f);
MOO_STACK_SETRETTORCV (moo, nargs); MOO_STACK_SETRETTORCV (moo, nargs);
break; break;
} }
/* TODO: free all duplicated string arguments... */ free_linked_cas (moo, rcv);
dcFree (dc);
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
noimpl: noimpl:
@ -402,14 +473,12 @@ inval:
goto softfail; goto softfail;
softfail: softfail:
/* TODO: free all duplicated string arguments... */ free_linked_cas (moo, rcv);
if (dc) dcFree(dc);
MOO_STACK_SETRETTOERROR (moo, nargs); MOO_STACK_SETRETTOERROR (moo, nargs);
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
hardfail: hardfail:
/* TODO: free all duplicated string arguments... */ free_linked_cas (moo, rcv);
if (dc) dcFree(dc);
return MOO_PF_HARD_FAILURE; return MOO_PF_HARD_FAILURE;
#else #else
@ -434,7 +503,7 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
name = MOO_STACK_GETARG(moo, nargs, 0); name = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR)) /* TODO: null check on the symbol name? */ if (!MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR)) /* TODO: null check on the symbol name? is '\0' contained in the middle of the name? */
{ {
moo_seterrnum (moo, MOO_EINVAL); moo_seterrnum (moo, MOO_EINVAL);
goto softfail; goto softfail;