added more string duplication and conversion functions

This commit is contained in:
hyunghwan.chung 2017-01-12 16:33:26 +00:00
parent ec3285da57
commit 750f529201
6 changed files with 265 additions and 103 deletions

View File

@ -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.
] ]
} }

View File

@ -651,6 +651,7 @@ int main (int argc, char* argv[])
return -1; return -1;
} }
{ {
moo_oow_t tab_size; moo_oow_t tab_size;

View File

@ -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,

View File

@ -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
* ========================================================================= */ * ========================================================================= */

View File

@ -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;
}

View File

@ -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 */
moo_seterrnum (moo, MOO_ENOIMPL); if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl;
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 */ /* the error code should be DC_ERROR_UNSUPPORTED_MODE */
moo_seterrnum (moo, MOO_ENOIMPL); if (dcGetError(dc) != DC_ERROR_NONE) goto noimpl;
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;
} }