From 70f9976af364b99edf6ba4f12ff4eff9e50f73bb Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sun, 15 Jan 2017 17:53:37 +0000 Subject: [PATCH] added moo_duputobcharswithheadroom(), moo_dupbtoucharswithheadroom() added moo_inttoooi() and made public moo_inttooow() enhanced the ffi module a bit more --- moo/lib/bigint.c | 12 +++ moo/lib/err.c | 6 ++ moo/lib/exec.c | 15 ++- moo/lib/main.c | 18 +++- moo/lib/moo-cmn.h | 2 +- moo/lib/moo-dos.h | 6 +- moo/lib/moo-prv.h | 6 -- moo/lib/moo.h | 56 ++++++++++-- moo/lib/obj.c | 2 +- moo/lib/sym.c | 35 ++++++- moo/lib/utl.c | 22 ++++- moo/mod/ffi.c | 229 ++++++++++++++++++++++++++++++---------------- 12 files changed, 299 insertions(+), 110 deletions(-) diff --git a/moo/lib/bigint.c b/moo/lib/bigint.c index b9f6495..cd83fb4 100644 --- a/moo/lib/bigint.c +++ b/moo/lib/bigint.c @@ -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 */ } +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) { #if (MOO_LIW_BITS == MOO_OOW_BITS) diff --git a/moo/lib/err.c b/moo/lib/err.c index 87adc50..9150688 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -195,10 +195,16 @@ moo_errnum_t moo_syserrtoerrnum (int e) { case ENOMEM: return MOO_ESYSMEM; case EINVAL: return MOO_EINVAL; + #if defined(EBUSY) case EBUSY: return MOO_EBUSY; + #endif case EACCES: return MOO_EACCES; + #if defined(EPERM) case EPERM: return MOO_EPERM; + #endif + #if defined(ENOTDIR) case ENOTDIR: return MOO_ENOTDIR; + #endif case ENOENT: return MOO_ENOENT; #if defined(EEXIST) case EEXIST: return MOO_EEXIST; diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 6945b53..08160a0 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -122,7 +122,7 @@ # define LOG_INST_3(moo,fmt,a1,a2,a3) #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__ */ # define __PRIMITIVE_NAME__ "<>" #else @@ -145,13 +145,15 @@ static MOO_INLINE void vm_gettime (moo_t* moo, moo_ntime_t* now) /* it must return NO_ERROR */ 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; /* TODO: handle overflow?? */ c = clock (); 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); #elif (CLOCKS_PER_SEC == 1000000L) 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: ... */ -#elif defined(__DOS__) && defined(_INTELC32_) +#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) clock_t c; c = clock (); 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); #elif (CLOCKS_PER_SEC == 1000000L) c += MOO_NSEC_TO_USEC(dur->nsec); diff --git a/moo/lib/main.c b/moo/lib/main.c index 053ca6d..4ee12c3 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -48,6 +48,7 @@ #elif defined(__DOS__) # include # include +# include #elif defined(macintosh) # include #else @@ -510,11 +511,20 @@ static moo_t* g_moo = MOO_NULL; /* ========================================================================= */ -#if defined(__DOS__) && defined(_INTELC32_) -static void (*prev_timer_intr_handler) (void); +#if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) +#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) static void timer_intr_handler (void) +#else +static void __interrupt timer_intr_handler (void) +#endif { /* _XSTACK *stk; @@ -551,7 +561,7 @@ static void arrange_process_switching (int sig) static void setup_tick (void) { -#if defined(__DOS__) && defined(_INTELC32_) +#if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) prev_timer_intr_handler = _dos_getvect (0x1C); _dos_setvect (0x1C, timer_intr_handler); @@ -587,7 +597,7 @@ static void setup_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); diff --git a/moo/lib/moo-cmn.h b/moo/lib/moo-cmn.h index 0907f55..679e2cb 100644 --- a/moo/lib/moo-cmn.h +++ b/moo/lib/moo-cmn.h @@ -561,7 +561,7 @@ typedef struct moo_t moo_t; # define MOO_IMPORT # define MOO_EXPORT # 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_EXPORT __declspec(dllexport) # define MOO_PRIVATE diff --git a/moo/lib/moo-dos.h b/moo/lib/moo-dos.h index 6bd8f1f..d22b6f3 100644 --- a/moo/lib/moo-dos.h +++ b/moo/lib/moo-dos.h @@ -47,7 +47,11 @@ # define MOO_SIZEOF___INT8 1 # define MOO_SIZEOF___INT16 2 # define MOO_SIZEOF___INT32 4 -# define MOO_SIZEOF___INT64 8 +# if (__WATCOMC__ < 1000) +# define MOO_SIZEOF___INT64 0 +# else +# define MOO_SIZEOF___INT64 8 +# endif # define MOO_SIZEOF___INT128 0 # define MOO_SIZEOF_OFF64_T 0 diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 14fb884..310ade2 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1003,12 +1003,6 @@ int moo_isint ( moo_oop_t x ); -int moo_inttooow ( - moo_t* moo, - moo_oop_t x, - moo_oow_t* w -); - moo_oop_t moo_addints ( moo_t* moo, moo_oop_t x, diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 229d99d..6de18b9 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1311,16 +1311,27 @@ MOO_EXPORT moo_oop_t moo_makesymbol ( moo_oow_t len ); -MOO_EXPORT moo_oop_t moo_makestring ( - moo_t* moo, - const moo_ooch_t* ptr, - moo_oow_t len +MOO_EXPORT moo_oop_t moo_makestringwithuchars ( + moo_t* moo, + const moo_uch_t* ptr, + 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_t* moo, - moo_oow_t w + moo_t* moo, + moo_oow_t w ); MOO_EXPORT moo_oop_t moo_ooitoint ( @@ -1328,6 +1339,19 @@ MOO_EXPORT moo_oop_t moo_ooitoint ( 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 * ========================================================================= */ @@ -1443,11 +1467,15 @@ int moo_convutobcstr ( #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_dupbtooochars(moo,bcs,bcslen,oocslen) moo_dupbtouchars(moo,bcs,bcslen,oocslen) # define moo_dupootobcstr(moo,oocs,bcslen) moo_duputobcstr(moo,oocs,bcslen) # define moo_dupbtooocstr(moo,bcs,oocslen) moo_dupbtoucstr(moo,bcs,oocslen) #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_duputooochars(moo,ucs,ucslen,oocslen) moo_duputobchars(moo,ucs,ucslen,oocslen) # define moo_dupootoucstr(moo,oocs,ucslen) moo_dupbtoucstr(moo,oocs,ucslen) @@ -1455,6 +1483,22 @@ int moo_convutobcstr ( #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_t* moo, const moo_bch_t* bcs, diff --git a/moo/lib/obj.c b/moo/lib/obj.c index d906163..fc771da 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -142,7 +142,7 @@ static MOO_INLINE moo_oop_t alloc_numeric_array (moo_t* moo, const void* ptr, mo } 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); } diff --git a/moo/lib/sym.c b/moo/lib/sym.c index c680281..6e1d78e 100644 --- a/moo/lib/sym.c +++ b/moo/lib/sym.c @@ -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); } -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); +#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 } diff --git a/moo/lib/utl.c b/moo/lib/utl.c index ea5d46f..d6b3d92 100644 --- a/moo/lib/utl.c +++ b/moo/lib/utl.c @@ -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_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; } - 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; inlen = bcslen; + + ptr = (moo_uch_t*)((moo_oob_t*)ptr + headroom_bytes); moo_convbtouchars (moo, bcs, &inlen, ptr, &outlen); /* 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; } -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_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; } - 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; inlen = ucslen; + ptr = (moo_bch_t*)((moo_oob_t*)ptr + headroom_bytes); moo_convutobchars (moo, ucs, &inlen, ptr, &outlen); 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; } +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_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; } - /* ----------------------------------------------------------------------- */ moo_uch_t* moo_dupuchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen) diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index 36fac29..22757d4 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -38,15 +38,43 @@ # include #endif -typedef void* ptr_t; +typedef struct link_t link_t; +struct link_t +{ + link_t* next; +}; typedef struct ffi_t ffi_t; struct ffi_t { MOO_OBJ_HEADER; 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) { 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; moo_oop_t name; + void* handle; +#if defined(USE_DYNCALL) + DCCallVM* dc; +#endif if (nargs != 1) { @@ -80,8 +112,27 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) goto softfail; } - rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)name)->slot, 0); - if (!rcv->handle) goto softfail; + if (rcv->handle) + { + 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, " %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle); 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, " %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); 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) ffi_t* rcv; moo_oop_t fun, sig, args; - DCCallVM* dc = MOO_NULL; moo_oow_t i, j; void* f; moo_oop_oop_t arr; int ellipsis = 0; - if (nargs < 3) goto inval; - rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + + if (nargs < 3) goto inval; fun = MOO_STACK_GETARG(moo, nargs, 0); sig = MOO_STACK_GETARG(moo, nargs, 1); 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); 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, " %p in %p\n", f, rcv->handle); - dcMode (dc, DC_CALL_C_DEFAULT); - dcReset (dc); + dcMode (rcv->dc, DC_CALL_C_DEFAULT); + dcReset (rcv->dc); i = 0; 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 */ - if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl; - dcReset (dc); + if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl; + dcReset (rcv->dc); ellipsis = 1; i++; } @@ -191,10 +241,10 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { 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 */ - if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl; + if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl; } continue; } @@ -207,31 +257,49 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { /* TODO: support more types... */ case 'c': - 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++; break; +/* TODO: added unsigned types */ case 'i': -/* TODO: use moo_inttoooi () */ - if (!MOO_OOP_IS_SMOOI(arg)) goto inval; - dcArgInt (dc, MOO_OOP_TO_SMOOI(arg)); + { + moo_ooi_t v; + if (moo_inttoooi(moo, arg, &v) == 0) goto inval; + dcArgInt (rcv->dc, i); j++; break; + } case 'l': -/* TODO: sanity check on the argument type - check if arr->slot[j] is SMOOI or bigint... */ -/* TODO: use moo_inttoooi () */ - dcArgLong (dc, MOO_OOP_TO_SMOOI(arg)); + { + moo_ooi_t v; + arg_as_long: + if (moo_inttoooi(moo, arg, &v) == 0) goto inval; + dcArgLong (rcv->dc, v); j++; break; + } 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++; break; + #else + goto arg_as_long; + #endif + } #if 0 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; /* TOOD: check if arg is a string. */ -/* TODO: free all duplicated strings after call */ + #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 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 - if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */ - dcArgPointer (dc, ptr); + dcArgPointer (rcv->dc, ptr); j++; break; } @@ -261,20 +331,22 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) #if defined(MOO_OOCH_IS_UCH) 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 - ptr = moo_dupootouchars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL); - #endif + ptr = moo_dupootoucharswithheadroom (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); + #endif - dcArgPointer (dc, ptr); + dcArgPointer (rcv->dc, ptr); j++; break; } default: - /* TODO: ERROR HANDLING */ - break; + /* invalid argument signature specifier */ + goto inval; } } @@ -288,7 +360,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) /* TODO: proper return value conversion */ case 'c': { - char r = dcCallChar (dc, f); + char r = dcCallChar (rcv->dc, f); MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r)); break; } @@ -297,7 +369,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_oop_t r; - r = moo_ooitoint (moo, dcCallInt (dc, f)); + r = moo_ooitoint (moo, dcCallInt (rcv->dc, f)); if (!r) goto hardfail; MOO_STACK_SETRET (moo, nargs, r); break; @@ -306,29 +378,30 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) case 'l': { 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; MOO_STACK_SETRET (moo, nargs, r); break; } - #if (STIX_SIZEOF_LONG_LONG > 0) case 'L': { - long long r = dcCallLongLong (dc, f); - 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) goto hardfail; - + #if (MOO_SIZEOF_LONG_LONG > 0) + moo_oop_t r; + # if (MOO_SIZEOF_LONG_LONG <= MOO_SIZEOF_OOI_T) + r = moo_ooitoint (moo, dcCallLongLong (rcv->dc, f)); + # else + # error UNSUPPORTED MOO_SIZEOF_LONG_LONG + # endif + if (!r) goto hardfail; MOO_STACK_SETRET (moo, nargs, r); break; + #else + goto ret_as_long; + #endif } - #endif + #if 0 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_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) - ptr = moo_dupbtooocstr (moo, r, &len); - if (!ptr) goto softfail; /* out of system memory or conversion error - still soft failure */ - s = moo_makestring(moo, ptr, len); - moo_freemem (moo, ptr); + s = moo_makestringwithbchars (moo, r, moo_countbcstr(r)); #else s = moo_makestring(moo, r, moo_countbcstr(r)); #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); break; @@ -363,20 +435,20 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_oop_t s; 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) s = moo_makestring(moo, r, moo_countucstr(r)); #else - ptr = moo_dupbtooocstr (moo, r, &len); - if (!ptr) goto softfail; /* out of system memory or conversion error - still soft failure */ - s = moo_makestring(moo, ptr, len); - moo_freemem (moo, ptr); + s = moo_makestringwithuchars(moo, r, moo_countucstr(r)); #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); break; @@ -384,13 +456,12 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) default: call_void: - dcCallVoid (dc, f); + dcCallVoid (rcv->dc, f); MOO_STACK_SETRETTORCV (moo, nargs); break; } -/* TODO: free all duplicated string arguments... */ - dcFree (dc); + free_linked_cas (moo, rcv); return MOO_PF_SUCCESS; noimpl: @@ -402,14 +473,12 @@ inval: goto softfail; softfail: -/* TODO: free all duplicated string arguments... */ - if (dc) dcFree(dc); + free_linked_cas (moo, rcv); MOO_STACK_SETRETTOERROR (moo, nargs); return MOO_PF_SUCCESS; hardfail: -/* TODO: free all duplicated string arguments... */ - if (dc) dcFree(dc); + free_linked_cas (moo, rcv); return MOO_PF_HARD_FAILURE; #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); 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); goto softfail;