added more string duplication and conversion functions
This commit is contained in:
parent
ec3285da57
commit
750f529201
@ -90,6 +90,7 @@ class MyObject(Object)
|
|||||||
ifFalse: [
|
ifFalse: [
|
||||||
(ffi call: #getpid signature: ')i' arguments: nil) dump.
|
(ffi call: #getpid signature: ')i' arguments: nil) dump.
|
||||||
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'fly away')) dump.
|
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'fly away')) dump.
|
||||||
|
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'jump down')) dump.
|
||||||
ffi close.
|
ffi close.
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -651,6 +651,7 @@ int main (int argc, char* argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
moo_oow_t tab_size;
|
moo_oow_t tab_size;
|
||||||
|
|
||||||
|
@ -303,7 +303,6 @@ MOO_EXPORT int moo_convutf8toucstr (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MOO_EXPORT moo_oow_t moo_uctoutf8 (
|
MOO_EXPORT moo_oow_t moo_uctoutf8 (
|
||||||
moo_uch_t uc,
|
moo_uch_t uc,
|
||||||
moo_bch_t* utf8,
|
moo_bch_t* utf8,
|
||||||
|
@ -1434,6 +1434,66 @@ int moo_convutobcstr (
|
|||||||
moo_oow_t* bcslen
|
moo_oow_t* bcslen
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
|
# 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_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)
|
||||||
|
# define moo_duputooocstr(moo,ucs,oocslen) moo_duputobcstr(moo,ucs,oocslen)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
MOO_EXPORT moo_uch_t* moo_dupbtouchars (
|
||||||
|
moo_t* moo,
|
||||||
|
const moo_bch_t* bcs,
|
||||||
|
moo_oow_t bcslen,
|
||||||
|
moo_oow_t* ucslen
|
||||||
|
);
|
||||||
|
|
||||||
|
MOO_EXPORT moo_bch_t* moo_duputobchars (
|
||||||
|
moo_t* moo,
|
||||||
|
const moo_uch_t* ucs,
|
||||||
|
moo_oow_t ucslen,
|
||||||
|
moo_oow_t* bcslen
|
||||||
|
);
|
||||||
|
|
||||||
|
MOO_EXPORT moo_uch_t* moo_dupbtoucstr (
|
||||||
|
moo_t* moo,
|
||||||
|
const moo_bch_t* bcs,
|
||||||
|
moo_oow_t* ucslen /* optional: length of returned string */
|
||||||
|
);
|
||||||
|
|
||||||
|
MOO_EXPORT moo_bch_t* moo_duputobcstr (
|
||||||
|
moo_t* moo,
|
||||||
|
const moo_uch_t* ucs,
|
||||||
|
moo_oow_t* bcslen /* optional: length of returned string */
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
|
# define moo_dupoochars(moo,oocs,oocslen) moo_dupuchars(moo,oocs,oocslen)
|
||||||
|
#else
|
||||||
|
# define moo_dupoochars(moo,oocs,oocslen) moo_dupbchars(moo,oocs,oocslen)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MOO_EXPORT moo_uch_t* moo_dupuchars (
|
||||||
|
moo_t* moo,
|
||||||
|
const moo_uch_t* ucs,
|
||||||
|
moo_oow_t ucslen
|
||||||
|
);
|
||||||
|
|
||||||
|
MOO_EXPORT moo_bch_t* moo_dupbchars (
|
||||||
|
moo_t* moo,
|
||||||
|
const moo_bch_t* bcs,
|
||||||
|
moo_oow_t bcslen
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
* MOO VM LOGGING
|
* MOO VM LOGGING
|
||||||
* ========================================================================= */
|
* ========================================================================= */
|
||||||
|
@ -672,40 +672,117 @@ 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_uch_t* moo_dupbtouchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t bcslen, moo_oow_t* ucslen)
|
||||||
{
|
{
|
||||||
moo_oow_t inlen, reqlen;
|
moo_oow_t inlen, outlen;
|
||||||
moo_uch_t* ptr;
|
moo_uch_t* ptr;
|
||||||
|
|
||||||
inlen = bcslen;
|
inlen = bcslen;
|
||||||
if (moo_convbtouchars (moo, bcs, &inlen, MOO_NULL, &reqlen) <= -1)
|
if (moo_convbtouchars (moo, bcs, &inlen, MOO_NULL, &outlen) <= -1)
|
||||||
{
|
{
|
||||||
/* note it's also an error if no full conversion is possible in this function */
|
/* note it's also an error if no full conversion is made in this function */
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = moo_allocmem (moo, reqlen * MOO_SIZEOF(moo_uch_t));
|
ptr = moo_allocmem (moo, (outlen + 1) * MOO_SIZEOF(moo_uch_t));
|
||||||
if (!ptr) return MOO_NULL;
|
if (!ptr) return MOO_NULL;
|
||||||
|
|
||||||
inlen = bcslen;
|
inlen = bcslen;
|
||||||
moo_convbtouchars (moo, bcs, &inlen, ptr, ucslen);
|
moo_convbtouchars (moo, bcs, &inlen, ptr, &outlen);
|
||||||
|
|
||||||
|
/* moo_convbtouchars() doesn't null-terminate the target.
|
||||||
|
* but in moo_dupbtouchars(), i allocate space. so i don't mind
|
||||||
|
* null-terminating it with 1 extra character overhead */
|
||||||
|
ptr[outlen] = '\0';
|
||||||
|
if (ucslen) *ucslen = outlen;
|
||||||
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_bch_t* moo_duputobchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen, moo_oow_t* bcslen)
|
||||||
{
|
{
|
||||||
moo_oow_t inlen, reqlen;
|
moo_oow_t inlen, outlen;
|
||||||
moo_bch_t* ptr;
|
moo_bch_t* ptr;
|
||||||
|
|
||||||
inlen = ucslen;
|
inlen = ucslen;
|
||||||
if (moo_convutobchars (moo, ucs, &inlen, MOO_NULL, &reqlen) <= -1)
|
if (moo_convutobchars (moo, ucs, &inlen, MOO_NULL, &outlen) <= -1)
|
||||||
{
|
{
|
||||||
/* note it's also an error if no full conversion is possible in this function */
|
/* note it's also an error if no full conversion is made in this function */
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = moo_allocmem (moo, reqlen * MOO_SIZEOF(moo_bch_t));
|
ptr = moo_allocmem (moo, (outlen + 1) * MOO_SIZEOF(moo_bch_t));
|
||||||
if (!ptr) return MOO_NULL;
|
if (!ptr) return MOO_NULL;
|
||||||
|
|
||||||
inlen = ucslen;
|
inlen = ucslen;
|
||||||
moo_convutobchars (moo, ucs, &inlen, ptr, bcslen);
|
moo_convutobchars (moo, ucs, &inlen, ptr, &outlen);
|
||||||
|
|
||||||
|
ptr[outlen] = '\0';
|
||||||
|
if (bcslen) *bcslen = outlen;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moo_uch_t* moo_dupbtoucstr (moo_t* moo, const moo_bch_t* bcs, moo_oow_t* ucslen)
|
||||||
|
{
|
||||||
|
moo_oow_t inlen, outlen;
|
||||||
|
moo_uch_t* ptr;
|
||||||
|
|
||||||
|
if (moo_convbtoucstr (moo, bcs, &inlen, MOO_NULL, &outlen) <= -1)
|
||||||
|
{
|
||||||
|
/* note it's also an error if no full conversion is made in this function */
|
||||||
|
return MOO_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
outlen++;
|
||||||
|
ptr = moo_allocmem (moo, outlen * MOO_SIZEOF(moo_uch_t));
|
||||||
|
if (!ptr) return MOO_NULL;
|
||||||
|
|
||||||
|
moo_convbtoucstr (moo, bcs, &inlen, ptr, &outlen);
|
||||||
|
if (ucslen) *ucslen = outlen;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
moo_bch_t* moo_duputobcstr (moo_t* moo, const moo_uch_t* ucs, moo_oow_t* bcslen)
|
||||||
|
{
|
||||||
|
moo_oow_t inlen, outlen;
|
||||||
|
moo_bch_t* ptr;
|
||||||
|
|
||||||
|
if (moo_convutobcstr (moo, ucs, &inlen, MOO_NULL, &outlen) <= -1)
|
||||||
|
{
|
||||||
|
/* note it's also an error if no full conversion is made in this function */
|
||||||
|
return MOO_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
outlen++;
|
||||||
|
ptr = moo_allocmem (moo, outlen * MOO_SIZEOF(moo_bch_t));
|
||||||
|
if (!ptr) return MOO_NULL;
|
||||||
|
|
||||||
|
moo_convutobcstr (moo, ucs, &inlen, ptr, &outlen);
|
||||||
|
if (bcslen) *bcslen = outlen;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
moo_uch_t* moo_dupuchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t ucslen)
|
||||||
|
{
|
||||||
|
moo_uch_t* ptr;
|
||||||
|
|
||||||
|
ptr = moo_allocmem (moo, (ucslen + 1) * MOO_SIZEOF(moo_uch_t));
|
||||||
|
if (!ptr) return MOO_NULL;
|
||||||
|
|
||||||
|
moo_copyuchars (ptr, ucs, ucslen);
|
||||||
|
ptr[ucslen] = '\0';
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
moo_bch_t* moo_dupbchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t bcslen)
|
||||||
|
{
|
||||||
|
moo_bch_t* ptr;
|
||||||
|
|
||||||
|
ptr = moo_allocmem (moo, (bcslen + 1) * MOO_SIZEOF(moo_bch_t));
|
||||||
|
if (!ptr) return MOO_NULL;
|
||||||
|
|
||||||
|
moo_copybchars (ptr, bcs, bcslen);
|
||||||
|
ptr[bcslen] = '\0';
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
208
moo/mod/ffi.c
208
moo/mod/ffi.c
@ -62,7 +62,7 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if (nargs != 1)
|
if (nargs != 1)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
||||||
@ -71,23 +71,23 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if (!MOO_ISTYPEOF(moo, name, MOO_OBJ_TYPE_CHAR) || !MOO_OBJ_GET_FLAGS_EXTRA(name)) /* 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);
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!moo->vmprim.dl_open)
|
if (!moo->vmprim.dl_open)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_ENOIMPL);
|
moo_seterrnum (moo, MOO_ENOIMPL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)name)->slot, 0);
|
rcv->handle = moo->vmprim.dl_open (moo, ((moo_oop_char_t)name)->slot, 0);
|
||||||
if (!rcv->handle) goto reterr;
|
if (!rcv->handle) goto softfail;
|
||||||
|
|
||||||
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);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
|
||||||
reterr:
|
softfail:
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs);
|
MOO_STACK_SETRETTOERROR (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if (nargs != 0)
|
if (nargs != 0)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
||||||
@ -107,7 +107,7 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if (!moo->vmprim.dl_open)
|
if (!moo->vmprim.dl_open)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_ENOIMPL);
|
moo_seterrnum (moo, MOO_ENOIMPL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOO_DEBUG1 (moo, "<ffi.close> %p\n", rcv->handle);
|
MOO_DEBUG1 (moo, "<ffi.close> %p\n", rcv->handle);
|
||||||
@ -118,31 +118,11 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
|
|||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
|
||||||
reterr:
|
softfail:
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs);
|
MOO_STACK_SETRETTOERROR (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
struct bcstr_node_t
|
|
||||||
{
|
|
||||||
stix_bch_t* ptr;
|
|
||||||
bcstr_node_t* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bcstr_node_t* dupbcstr (moo_t* moo, bcstr_node_t* bcstr, const moo_bch_t* ptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
moo_freemem (
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_bcstr_node (moo_t* moo, bcstr_node_t* bcstr)
|
|
||||||
{
|
|
||||||
moo_freemem (moo, bcstr->ptr);
|
|
||||||
moo_freemem (moo, bcstr);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
@ -153,31 +133,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
void* f;
|
void* f;
|
||||||
moo_oop_oop_t arr;
|
moo_oop_oop_t arr;
|
||||||
int ellipsis = 0;
|
int ellipsis = 0;
|
||||||
struct bcstr_node_t* bcstr;
|
|
||||||
|
|
||||||
if (nargs < 3)
|
if (nargs < 3) goto inval;
|
||||||
{
|
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
|
||||||
goto reterr;
|
|
||||||
}
|
|
||||||
|
|
||||||
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
||||||
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);
|
||||||
|
|
||||||
if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0)
|
if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval;
|
||||||
{
|
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
|
||||||
goto reterr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (MOO_OBJ_GET_SIZE(sig) > 1 && MOO_CLASSOF(moo,args) != moo->_array) /* TODO: check if arr is a kind of array??? or check if it's indexed */
|
/* TODO: check if arr is a kind of array??? or check if it's indexed */
|
||||||
{
|
if (MOO_OBJ_GET_SIZE(sig) > 1 && MOO_CLASSOF(moo,args) != moo->_array) goto inval;
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
|
||||||
goto reterr;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
f = MOO_OOP_TO_SMPTR(fun);
|
f = MOO_OOP_TO_SMPTR(fun);
|
||||||
@ -187,24 +155,21 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
|
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
|
||||||
goto reterr;
|
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 (dc, DC_CALL_C_DEFAULT);
|
||||||
dcReset (dc);*/
|
dcReset (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 (dc, DC_CALL_C_ELLIPSIS);
|
||||||
if (dcGetError(dc) != DC_ERROR_NONE)
|
|
||||||
{
|
/* 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;
|
||||||
moo_seterrnum (moo, MOO_ENOIMPL);
|
|
||||||
goto reterr;
|
|
||||||
}
|
|
||||||
dcReset (dc);
|
dcReset (dc);
|
||||||
ellipsis = 1;
|
ellipsis = 1;
|
||||||
i++;
|
i++;
|
||||||
@ -213,6 +178,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
for (j = 0; i < MOO_OBJ_GET_SIZE(sig); i++)
|
for (j = 0; i < MOO_OBJ_GET_SIZE(sig); i++)
|
||||||
{
|
{
|
||||||
moo_ooch_t fmtc;
|
moo_ooch_t fmtc;
|
||||||
|
moo_oop_t arg;
|
||||||
|
|
||||||
fmtc = ((moo_oop_char_t)sig)->slot[i];
|
fmtc = ((moo_oop_char_t)sig)->slot[i];
|
||||||
|
|
||||||
@ -227,46 +193,43 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
{
|
{
|
||||||
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS);
|
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS);
|
||||||
|
|
||||||
if (dcGetError(dc) != DC_ERROR_NONE)
|
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */
|
||||||
{
|
if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl;
|
||||||
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */
|
|
||||||
moo_seterrnum (moo, MOO_ENOIMPL);
|
|
||||||
goto reterr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j >= MOO_OBJ_GET_SIZE(arr))
|
/* more items in signature than the actual argument */
|
||||||
{
|
if (j >= MOO_OBJ_GET_SIZE(arr)) goto inval;
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
|
||||||
goto reterr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
arg = arr->slot[j];
|
||||||
switch (fmtc)
|
switch (fmtc)
|
||||||
{
|
{
|
||||||
/* TODO: support more types... */
|
/* TODO: support more types... */
|
||||||
case 'c':
|
case 'c':
|
||||||
/* TODO: sanity check on the argument type */
|
|
||||||
|
if (!MOO_OOP_IS_CHAR(arg)) goto inval;
|
||||||
dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[j]));
|
dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[j]));
|
||||||
j++;
|
j++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
/* TODO: use moo_inttoooi () */
|
/* TODO: use moo_inttoooi () */
|
||||||
dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[j]));
|
if (!MOO_OOP_IS_SMOOI(arg)) goto inval;
|
||||||
|
dcArgInt (dc, MOO_OOP_TO_SMOOI(arg));
|
||||||
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 () */
|
/* TODO: use moo_inttoooi () */
|
||||||
dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[j]));
|
dcArgLong (dc, MOO_OOP_TO_SMOOI(arg));
|
||||||
j++;
|
j++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
/* TODO: use moo_inttoooi () */
|
/* TODO: use moo_inttoooi () */
|
||||||
dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[j]));
|
dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arg));
|
||||||
j++;
|
j++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -275,15 +238,34 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
#endif
|
#endif
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
moo_oow_t bcslen, ucslen;
|
moo_bch_t* ptr;
|
||||||
moo_bch_t bcs[1024]; /*TODO: dynamic length.... */
|
|
||||||
|
|
||||||
ucslen = MOO_OBJ_GET_SIZE(arr->slot[j]);
|
/* TOOD: check if arg is a string. */
|
||||||
bcslen = MOO_COUNTOF(bcs);
|
/* TODO: free all duplicated strings after call */
|
||||||
moo_convootobcstr (moo, ((moo_oop_char_t)arr->slot[j])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
|
ptr = moo_dupootobchars (moo, ((moo_oop_char_t)arg)->slot, MOO_OBJ_GET_SIZE(arg), MOO_NULL);
|
||||||
|
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
|
||||||
|
#else
|
||||||
|
ptr = moo_dupoochars (moo, ((moo_oop_char_t)arg)->slot, MOO_OBJ_GET_SIZE(arg));
|
||||||
|
#endif
|
||||||
|
|
||||||
bcs[bcslen] = '\0';
|
dcArgPointer (dc, ptr);
|
||||||
dcArgPointer (dc, bcs);
|
j++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
{
|
||||||
|
moo_uch_t* ptr;
|
||||||
|
|
||||||
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
|
ptr = moo_dupoochars (moo, ((moo_oop_char_t)arg)->slot, MOO_OBJ_GET_SIZE(arg));
|
||||||
|
#else
|
||||||
|
ptr = moo_dupootouchars (moo, ((moo_oop_char_t)arg)->slot, MOO_OBJ_GET_SIZE(arg), MOO_NULL);
|
||||||
|
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dcArgPointer (dc, ptr);
|
||||||
j++;
|
j++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -294,6 +276,8 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: clean up strings duplicated... using moo_dupootobchars... */
|
||||||
|
|
||||||
if (i >= MOO_OBJ_GET_SIZE(sig)) goto call_void;
|
if (i >= MOO_OBJ_GET_SIZE(sig)) goto call_void;
|
||||||
|
|
||||||
switch (((moo_oop_char_t)sig)->slot[i])
|
switch (((moo_oop_char_t)sig)->slot[i])
|
||||||
@ -312,7 +296,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 (dc, f));
|
||||||
if (!r) goto oops;
|
if (!r) goto hardfail;
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -321,7 +305,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, dcCallLong (dc, f));
|
r = moo_ooitoint (moo, dcCallLong (dc, f));
|
||||||
if (!r) goto oops;
|
if (!r) goto hardfail;
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -337,7 +321,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
#else
|
#else
|
||||||
# error TODO:...
|
# error TODO:...
|
||||||
#endif
|
#endif
|
||||||
if (!rr) goto oops;
|
if (!rr) goto hardfail;
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
break;
|
break;
|
||||||
@ -352,16 +336,45 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
moo_oow_t bcslen, ucslen;
|
|
||||||
moo_ooch_t ucs[1024]; /* TOOD: buffer size... */
|
|
||||||
moo_oop_t s;
|
moo_oop_t s;
|
||||||
char* r = dcCallPointer (dc, f);
|
moo_bch_t* r;
|
||||||
|
moo_ooch_t* ptr;
|
||||||
|
moo_oow_t len;
|
||||||
|
|
||||||
bcslen = strlen(r);
|
r = dcCallPointer (dc, f);
|
||||||
moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* error check... */
|
|
||||||
|
|
||||||
s = moo_makestring(moo, ucs, ucslen);
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
if (!s) goto oops;
|
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);
|
||||||
|
#else
|
||||||
|
s = moo_makestring(moo, r, moo_countbcstr(r));
|
||||||
|
#endif
|
||||||
|
if (!s) goto hardfail; /* out of object memory - hard failure*/
|
||||||
|
|
||||||
|
MOO_STACK_SETRET (moo, nargs, s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
{
|
||||||
|
moo_oop_t s;
|
||||||
|
moo_uch_t* r;
|
||||||
|
moo_ooch_t* ptr;
|
||||||
|
moo_oow_t len;
|
||||||
|
|
||||||
|
r = dcCallPointer (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);
|
||||||
|
#endif
|
||||||
|
if (!s) goto hardfail; /* out of object memory - hard failure*/
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, s);
|
MOO_STACK_SETRET (moo, nargs, s);
|
||||||
break;
|
break;
|
||||||
@ -374,15 +387,26 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: free all duplicated string arguments... */
|
||||||
dcFree (dc);
|
dcFree (dc);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
|
||||||
reterr:
|
noimpl:
|
||||||
|
moo_seterrnum (moo, MOO_ENOIMPL);
|
||||||
|
goto softfail;
|
||||||
|
|
||||||
|
inval:
|
||||||
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
|
goto softfail;
|
||||||
|
|
||||||
|
softfail:
|
||||||
|
/* TODO: free all duplicated string arguments... */
|
||||||
if (dc) dcFree(dc);
|
if (dc) dcFree(dc);
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs);
|
MOO_STACK_SETRETTOERROR (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
|
||||||
oops:
|
hardfail:
|
||||||
|
/* TODO: free all duplicated string arguments... */
|
||||||
if (dc) dcFree(dc);
|
if (dc) dcFree(dc);
|
||||||
return MOO_PF_HARD_FAILURE;
|
return MOO_PF_HARD_FAILURE;
|
||||||
|
|
||||||
@ -402,7 +426,7 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
|
|||||||
if (nargs != 1)
|
if (nargs != 1)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
|
||||||
@ -411,17 +435,17 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
|
|||||||
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? */
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!moo->vmprim.dl_getsym)
|
if (!moo->vmprim.dl_getsym)
|
||||||
{
|
{
|
||||||
moo_seterrnum (moo, MOO_ENOIMPL);
|
moo_seterrnum (moo, MOO_ENOIMPL);
|
||||||
goto reterr;
|
goto softfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)name)->slot);
|
sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)name)->slot);
|
||||||
if (!sym) goto reterr;
|
if (!sym) goto softfail;
|
||||||
|
|
||||||
MOO_DEBUG4 (moo, "<ffi.getsym> %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, rcv->handle);
|
MOO_DEBUG4 (moo, "<ffi.getsym> %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, rcv->handle);
|
||||||
|
|
||||||
@ -429,7 +453,7 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
|
|||||||
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(sym));
|
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(sym));
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
|
|
||||||
reterr:
|
softfail:
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs);
|
MOO_STACK_SETRETTOERROR (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user