added more code to ffi

This commit is contained in:
hyunghwan.chung 2017-01-11 15:33:03 +00:00
parent f23486468d
commit d130ec02ec
5 changed files with 259 additions and 206 deletions

View File

@ -88,8 +88,9 @@ class MyObject(Object)
(ffi isError) (ffi isError)
ifTrue: [System logNl: 'cannot open libc.so' ] ifTrue: [System logNl: 'cannot open libc.so' ]
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 close. ffi close.
] ]
} }
} }

View File

@ -242,4 +242,4 @@ extend MyObject
System logNl: JJJ. System logNl: JJJ.
System logNl: -200 asString. System logNl: -200 asString.
} }
} }

View File

@ -29,14 +29,14 @@
#include "moo-cmn.h" #include "moo-cmn.h"
/**@file /**\file
* This file provides a red-black tree encapsulated in the #moo_rbt_t type that * This file provides a red-black tree encapsulated in the #moo_rbt_t type that
* implements a self-balancing binary search tree.Its interface is very close * implements a self-balancing binary search tree.Its interface is very close
* to #moo_htb_t. * to #moo_htb_t.
* *
* This sample code adds a series of keys and values and print them * This sample code adds a series of keys and values and print them
* in descending key order. * in descending key order.
* @code * \code
* #include <moo/cmn/rbt.h> * #include <moo/cmn/rbt.h>
* #include <moo/cmn/mem.h> * #include <moo/cmn/mem.h>
* #include <moo/cmn/sio.h> * #include <moo/cmn/sio.h>
@ -67,7 +67,7 @@
* moo_rbt_close (s1); * moo_rbt_close (s1);
* return 0; * return 0;
* } * }
* @endcode * \endcode
*/ */
typedef struct moo_rbt_t moo_rbt_t; typedef struct moo_rbt_t moo_rbt_t;
@ -99,9 +99,9 @@ typedef enum moo_rbt_id_t moo_rbt_id_t;
* The moo_rbt_copier_t type defines a pair contruction callback. * The moo_rbt_copier_t type defines a pair contruction callback.
*/ */
typedef void* (*moo_rbt_copier_t) ( typedef void* (*moo_rbt_copier_t) (
moo_rbt_t* rbt /* red-black tree */, moo_rbt_t* rbt /**< red-black tree */,
void* dptr /* pointer to a key or a value */, void* dptr /**< pointer to a key or a value */,
moo_oow_t dlen /* length of a key or a value */ moo_oow_t dlen /**< length of a key or a value */
); );
/** /**
@ -109,7 +109,7 @@ typedef void* (*moo_rbt_copier_t) (
*/ */
typedef void (*moo_rbt_freeer_t) ( typedef void (*moo_rbt_freeer_t) (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
void* dptr, /**< pointer to a key or a value */ void* dptr, /**< pointer to a key or a value */
moo_oow_t dlen /**< length of a key or a value */ moo_oow_t dlen /**< length of a key or a value */
); );
@ -123,9 +123,9 @@ typedef void (*moo_rbt_freeer_t) (
typedef int (*moo_rbt_comper_t) ( typedef int (*moo_rbt_comper_t) (
const moo_rbt_t* rbt, /**< red-black tree */ const moo_rbt_t* rbt, /**< red-black tree */
const void* kptr1, /**< key pointer */ const void* kptr1, /**< key pointer */
moo_oow_t klen1, /**< key length */ moo_oow_t klen1, /**< key length */
const void* kptr2, /**< key pointer */ const void* kptr2, /**< key pointer */
moo_oow_t klen2 /**< key length */ moo_oow_t klen2 /**< key length */
); );
/** /**
@ -152,8 +152,8 @@ typedef moo_rbt_walk_t (*moo_rbt_walker_t) (
/** /**
* The moo_rbt_cbserter_t type defines a callback function for moo_rbt_cbsert(). * The moo_rbt_cbserter_t type defines a callback function for moo_rbt_cbsert().
* The moo_rbt_cbserter() function calls it to allocate a new pair for the * The moo_rbt_cbserter() function calls it to allocate a new pair for the
* key pointed to by @a kptr of the length @a klen and the callback context * key pointed to by \a kptr of the length \a klen and the callback context
* @a ctx. The second parameter @a pair is passed the pointer to the existing * \a ctx. The second parameter \a pair is passed the pointer to the existing
* pair for the key or #MOO_NULL in case of no existing key. The callback * pair for the key or #MOO_NULL in case of no existing key. The callback
* must return a pointer to a new or a reallocated pair. When reallocating the * must return a pointer to a new or a reallocated pair. When reallocating the
* existing pair, this callback must destroy the existing pair and return the * existing pair, this callback must destroy the existing pair and return the
@ -162,9 +162,9 @@ typedef moo_rbt_walk_t (*moo_rbt_walker_t) (
typedef moo_rbt_pair_t* (*moo_rbt_cbserter_t) ( typedef moo_rbt_pair_t* (*moo_rbt_cbserter_t) (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
moo_rbt_pair_t* pair, /**< pair pointer */ moo_rbt_pair_t* pair, /**< pair pointer */
void* kptr, /**< key pointer */ void* kptr, /**< key pointer */
moo_oow_t klen, /**< key length */ moo_oow_t klen, /**< key length */
void* ctx /**< callback context */ void* ctx /**< callback context */
); );
/** /**
@ -177,7 +177,7 @@ struct moo_rbt_pair_t
{ {
struct struct
{ {
void* ptr; void* ptr;
moo_oow_t len; moo_oow_t len;
} key; } key;
@ -290,13 +290,13 @@ MOO_EXPORT const moo_rbt_style_t* moo_getrbtstyle (
/** /**
* The moo_rbt_open() function creates a red-black tree. * The moo_rbt_open() function creates a red-black tree.
* @return moo_rbt_t pointer on success, MOO_NULL on failure. * \return moo_rbt_t pointer on success, MOO_NULL on failure.
*/ */
MOO_EXPORT moo_rbt_t* moo_rbt_open ( MOO_EXPORT moo_rbt_t* moo_rbt_open (
moo_t* moo, moo_t* moo,
moo_oow_t xtnsize, /**< extension size in bytes */ moo_oow_t xtnsize, /**< extension size in bytes */
int kscale, /**< key scale */ int kscale, /**< key scale */
int vscale /**< value scale */ int vscale /**< value scale */
); );
/** /**
@ -312,8 +312,8 @@ MOO_EXPORT void moo_rbt_close (
MOO_EXPORT int moo_rbt_init ( MOO_EXPORT int moo_rbt_init (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
moo_t* moo, moo_t* moo,
int kscale, /**< key scale */ int kscale, /**< key scale */
int vscale /**< value scale */ int vscale /**< value scale */
); );
/** /**
@ -357,13 +357,13 @@ MOO_EXPORT moo_oow_t moo_rbt_getsize (
* The moo_rbt_search() function searches red-black tree to find a pair with a * The moo_rbt_search() function searches red-black tree to find a pair with a
* matching key. It returns the pointer to the pair found. If it fails * matching key. It returns the pointer to the pair found. If it fails
* to find one, it returns MOO_NULL. * to find one, it returns MOO_NULL.
* @return pointer to the pair with a maching key, * \return pointer to the pair with a maching key,
* or MOO_NULL if no match is found. * or MOO_NULL if no match is found.
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_search ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_search (
const moo_rbt_t* rbt, /**< red-black tree */ const moo_rbt_t* rbt, /**< red-black tree */
const void* kptr, /**< key pointer */ const void* kptr, /**< key pointer */
moo_oow_t klen /**< the size of the key */ moo_oow_t klen /**< the size of the key */
); );
/** /**
@ -371,56 +371,56 @@ MOO_EXPORT moo_rbt_pair_t* moo_rbt_search (
* matching key. If one is found, it updates the pair. Otherwise, it inserts * matching key. If one is found, it updates the pair. Otherwise, it inserts
* a new pair with the key and the value given. It returns the pointer to the * a new pair with the key and the value given. It returns the pointer to the
* pair updated or inserted. * pair updated or inserted.
* @return a pointer to the updated or inserted pair on success, * \return a pointer to the updated or inserted pair on success,
* MOO_NULL on failure. * MOO_NULL on failure.
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_upsert ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_upsert (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */ void* kptr, /**< key pointer */
moo_oow_t klen, /**< key length */ moo_oow_t klen, /**< key length */
void* vptr, /**< value pointer */ void* vptr, /**< value pointer */
moo_oow_t vlen /**< value length */ moo_oow_t vlen /**< value length */
); );
/** /**
* The moo_rbt_ensert() function inserts a new pair with the key and the value * The moo_rbt_ensert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns * given. If there exists a pair with the key given, the function returns
* the pair containing the key. * the pair containing the key.
* @return pointer to a pair on success, MOO_NULL on failure. * \return pointer to a pair on success, MOO_NULL on failure.
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_ensert ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_ensert (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */ void* kptr, /**< key pointer */
moo_oow_t klen, /**< key length */ moo_oow_t klen, /**< key length */
void* vptr, /**< value pointer */ void* vptr, /**< value pointer */
moo_oow_t vlen /**< value length */ moo_oow_t vlen /**< value length */
); );
/** /**
* The moo_rbt_insert() function inserts a new pair with the key and the value * The moo_rbt_insert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns * given. If there exists a pair with the key given, the function returns
* MOO_NULL without channging the value. * MOO_NULL without channging the value.
* @return pointer to the pair created on success, MOO_NULL on failure. * \return pointer to the pair created on success, MOO_NULL on failure.
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_insert ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_insert (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */ void* kptr, /**< key pointer */
moo_oow_t klen, /**< key length */ moo_oow_t klen, /**< key length */
void* vptr, /**< value pointer */ void* vptr, /**< value pointer */
moo_oow_t vlen /**< value length */ moo_oow_t vlen /**< value length */
); );
/** /**
* The moo_rbt_update() function updates the value of an existing pair * The moo_rbt_update() function updates the value of an existing pair
* with a matching key. * with a matching key.
* @return pointer to the pair on success, MOO_NULL on no matching pair * \return pointer to the pair on success, MOO_NULL on no matching pair
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_update ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_update (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */ void* kptr, /**< key pointer */
moo_oow_t klen, /**< key length */ moo_oow_t klen, /**< key length */
void* vptr, /**< value pointer */ void* vptr, /**< value pointer */
moo_oow_t vlen /**< value length */ moo_oow_t vlen /**< value length */
); );
/** /**
@ -431,7 +431,7 @@ MOO_EXPORT moo_rbt_pair_t* moo_rbt_update (
* a new pair if the key is not found and appends the new value to the * a new pair if the key is not found and appends the new value to the
* existing value delimited by a comma if the key is found. * existing value delimited by a comma if the key is found.
* *
* @code * \code
* moo_rbt_walk_t print_map_pair (moo_rbt_t* map, moo_rbt_pair_t* pair, void* ctx) * moo_rbt_walk_t print_map_pair (moo_rbt_t* map, moo_rbt_pair_t* pair, void* ctx)
* { * {
* moo_printf (MOO_T("%.*s[%d] => %.*s[%d]\n"), * moo_printf (MOO_T("%.*s[%d] => %.*s[%d]\n"),
@ -508,24 +508,24 @@ MOO_EXPORT moo_rbt_pair_t* moo_rbt_update (
* moo_rbt_close (s1); * moo_rbt_close (s1);
* return 0; * return 0;
* } * }
* @endcode * \endcode
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_cbsert ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_cbsert (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */ void* kptr, /**< key pointer */
moo_oow_t klen, /**< key length */ moo_oow_t klen, /**< key length */
moo_rbt_cbserter_t cbserter, /**< callback function */ moo_rbt_cbserter_t cbserter, /**< callback function */
void* ctx /**< callback context */ void* ctx /**< callback context */
); );
/** /**
* The moo_rbt_delete() function deletes a pair with a matching key * The moo_rbt_delete() function deletes a pair with a matching key
* @return 0 on success, -1 on failure * \return 0 on success, -1 on failure
*/ */
MOO_EXPORT int moo_rbt_delete ( MOO_EXPORT int moo_rbt_delete (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
const void* kptr, /**< key pointer */ const void* kptr, /**< key pointer */
moo_oow_t klen /**< key size */ moo_oow_t klen /**< key size */
); );
/** /**
@ -542,7 +542,7 @@ MOO_EXPORT void moo_rbt_clear (
MOO_EXPORT void moo_rbt_walk ( MOO_EXPORT void moo_rbt_walk (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
moo_rbt_walker_t walker, /**< callback function for each pair */ moo_rbt_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */ void* ctx /**< pointer to user-specific data */
); );
/** /**
@ -552,32 +552,32 @@ MOO_EXPORT void moo_rbt_walk (
MOO_EXPORT void moo_rbt_rwalk ( MOO_EXPORT void moo_rbt_rwalk (
moo_rbt_t* rbt, /**< red-black tree */ moo_rbt_t* rbt, /**< red-black tree */
moo_rbt_walker_t walker, /**< callback function for each pair */ moo_rbt_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */ void* ctx /**< pointer to user-specific data */
); );
/** /**
* The moo_rbt_allocpair() function allocates a pair for a key and a value * The moo_rbt_allocpair() function allocates a pair for a key and a value
* given. But it does not chain the pair allocated into the red-black tree @a rbt. * given. But it does not chain the pair allocated into the red-black tree \a rbt.
* Use this function at your own risk. * Use this function at your own risk.
* *
* Take note of he following special behavior when the copier is * Take note of he following special behavior when the copier is
* #MOO_RBT_COPIER_INLINE. * #MOO_RBT_COPIER_INLINE.
* - If @a kptr is #MOO_NULL, the key space of the size @a klen is reserved but * - If \a kptr is #MOO_NULL, the key space of the size \a klen is reserved but
* not propagated with any data. * not propagated with any data.
* - If @a vptr is #MOO_NULL, the value space of the size @a vlen is reserved * - If \a vptr is #MOO_NULL, the value space of the size \a vlen is reserved
* but not propagated with any data. * but not propagated with any data.
*/ */
MOO_EXPORT moo_rbt_pair_t* moo_rbt_allocpair ( MOO_EXPORT moo_rbt_pair_t* moo_rbt_allocpair (
moo_rbt_t* rbt, moo_rbt_t* rbt,
void* kptr, void* kptr,
moo_oow_t klen, moo_oow_t klen,
void* vptr, void* vptr,
moo_oow_t vlen moo_oow_t vlen
); );
/** /**
* The moo_rbt_freepair() function destroys a pair. But it does not detach * The moo_rbt_freepair() function destroys a pair. But it does not detach
* the pair destroyed from the red-black tree @a rbt. Use this function at your * the pair destroyed from the red-black tree \a rbt. Use this function at your
* own risk. * own risk.
*/ */
MOO_EXPORT void moo_rbt_freepair ( MOO_EXPORT void moo_rbt_freepair (
@ -590,10 +590,10 @@ MOO_EXPORT void moo_rbt_freepair (
*/ */
MOO_EXPORT int moo_rbt_dflcomp ( MOO_EXPORT int moo_rbt_dflcomp (
const moo_rbt_t* rbt, const moo_rbt_t* rbt,
const void* kptr1, const void* kptr1,
moo_oow_t klen1, moo_oow_t klen1,
const void* kptr2, const void* kptr2,
moo_oow_t klen2 moo_oow_t klen2
); );
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -45,7 +45,7 @@ struct __utf8_t
moo_uint8_t fbyte; /* mask to the first utf8 byte */ moo_uint8_t fbyte; /* mask to the first utf8 byte */
moo_uint8_t mask; moo_uint8_t mask;
moo_uint8_t fmask; moo_uint8_t fmask;
int length; /* number of bytes */ int length; /* number of bytes */
}; };
typedef struct __utf8_t __utf8_t; typedef struct __utf8_t __utf8_t;

View File

@ -122,12 +122,36 @@ reterr:
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)
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;
void* f;
moo_oop_oop_t arr;
int ellipsis = 0;
struct bcstr_node_t* bcstr;
if (nargs < 3) if (nargs < 3)
{ {
@ -146,192 +170,220 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
goto reterr; goto reterr;
} }
#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 */ 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 */
{ {
moo_seterrnum (moo, MOO_EINVAL); moo_seterrnum (moo, MOO_EINVAL);
goto reterr; goto reterr;
} }
#endif
f = MOO_OOP_TO_SMPTR(fun);
arr = (moo_oop_oop_t)args;
dc = dcNewCallVM (4096); /* TODO: right size? */
if (!dc)
{ {
moo_oow_t i; moo_seterrnum (moo, moo_syserrtoerrnum(errno));
DCCallVM* dc; goto reterr;
void* f; }
moo_oop_oop_t arr;
int mode_set;
f = MOO_OOP_TO_SMPTR(fun); MOO_DEBUG2 (moo, "<ffi.call> %p in %p\n", f, rcv->handle);
arr = (moo_oop_oop_t)args;
dc = dcNewCallVM (4096); /*dcMode (dc, DC_CALL_C_DEFAULT);
if (!dc) dcReset (dc);*/
i = 0;
if (i < MOO_OBJ_GET_SIZE(sig) && ((moo_oop_char_t)sig)->slot[i] == '|')
{
dcMode (dc, DC_CALL_C_ELLIPSIS);
if (dcGetError(dc) != DC_ERROR_NONE)
{ {
moo_seterrnum (moo, moo_syserrtoerrnum(errno)); /* the error code should be DC_ERROR_UNSUPPORTED_MODE */
moo_seterrnum (moo, MOO_ENOIMPL);
goto reterr;
}
dcReset (dc);
ellipsis = 1;
i++;
}
for (j = 0; i < MOO_OBJ_GET_SIZE(sig); i++)
{
moo_ooch_t fmtc;
fmtc = ((moo_oop_char_t)sig)->slot[i];
if (fmtc == ')')
{
i++;
break;
}
else if (fmtc == '|')
{
if (ellipsis)
{
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS);
if (dcGetError(dc) != DC_ERROR_NONE)
{
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */
moo_seterrnum (moo, MOO_ENOIMPL);
goto reterr;
}
}
continue;
}
if (j >= MOO_OBJ_GET_SIZE(arr))
{
moo_seterrnum (moo, MOO_EINVAL);
goto reterr; goto reterr;
} }
MOO_DEBUG2 (moo, "<ffi.call> %p in %p\n", f, rcv->handle); switch (fmtc)
/*dcMode (dc, DC_CALL_C_DEFAULT);
dcReset (dc);*/
/*for (i = 1; i < MOO_OBJ_GET_SIZE(sig); i++)
{ {
if (((moo_oop_char_t)sig)->slot[i] == '|') /* TODO: support more types... */
{
dcMode (dc, DC_CALL_C_ELLIPSIS);
MOO_DEBUG0 (moo, "CALL MODE 111 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
mode_set = 1;
break;
}
}
if (!mode_set) */ dcMode (dc, DC_CALL_C_DEFAULT);
for (i = 1; i < MOO_OBJ_GET_SIZE(sig); i++)
{
MOO_DEBUG1 (moo, "FFI: CALLING ARG %c\n", ((moo_oop_char_t)sig)->slot[i]);
switch (((moo_oop_char_t)sig)->slot[i])
{
/* TODO: support more types... */
/*
case '|':
dcMode (dc, DC_CALL_C_ELLIPSIS_VARARGS);
MOO_DEBUG2 (moo, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MODE);
break;
*/
case 'c':
/* TODO: sanity check on the argument type */
dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[i - 1]));
break;
case 'i':
/* TODO: use moo_inttoooi () */
dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 1]));
break;
case 'l':
/* TODO: use moo_inttoooi () */
dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 1]));
break;
case 'L':
/* TODO: use moo_inttoooi () */
dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[i - 1]));
break;
#if 0
case 'B': /* byte array */
#endif
case 's':
{
moo_oow_t bcslen, ucslen;
moo_bch_t bcs[1024];
ucslen = MOO_OBJ_GET_SIZE(arr->slot[i - 1]);
moo_convootobchars (moo, ((moo_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */
bcs[bcslen] = '\0';
dcArgPointer (dc, bcs);
break;
}
default:
/* TODO: ERROR HANDLING */
break;
}
}
switch (((moo_oop_char_t)sig)->slot[0])
{
/* TODO: support more types... */
/* TODO: proper return value conversion */
case 'c': case 'c':
{ /* TODO: sanity check on the argument type */
char r = dcCallChar (dc, f); dcArgChar (dc, MOO_OOP_TO_CHAR(arr->slot[j]));
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r)); j++;
break; break;
}
case 'i': case 'i':
{ /* TODO: use moo_inttoooi () */
moo_oop_t r; dcArgInt (dc, MOO_OOP_TO_SMOOI(arr->slot[j]));
r = moo_ooitoint (moo, dcCallInt (dc, f)); j++;
if (!r) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, r);
break; break;
}
case 'l': case 'l':
{ /* TODO: use moo_inttoooi () */
moo_oop_t r; dcArgLong (dc, MOO_OOP_TO_SMOOI(arr->slot[j]));
r = moo_ooitoint (moo, dcCallLong (dc, f)); j++;
if (!r) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, r);
break; break;
}
#if (STIX_SIZEOF_LONG_LONG > 0)
case 'L': case 'L':
{ /* TODO: use moo_inttoooi () */
long long r = dcCallLongLong (dc, f); dcArgLongLong (dc, MOO_OOP_TO_SMOOI(arr->slot[j]));
mod_oop_t r; j++;
#if STIX_SIZEOF_LONG_LONG <= STIX_SIZEOF_LONG
r = moo_ooitoint (moo, dcCallLongLong (dc, f));
#else
# error TODO:...
#endif
if (!rr) return MOD_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, r);
break; break;
}
#endif
#if 0 #if 0
case 'b': /* byte array */ case 'B': /* byte array */
{
}
#endif #endif
case 's':
case 'B':
{ {
moo_oow_t bcslen, ucslen; moo_oow_t bcslen, ucslen;
moo_ooch_t ucs[1024]; moo_bch_t bcs[1024]; /*TODO: dynamic length.... */
moo_oop_t s;
char* r = dcCallPointer (dc, f);
bcslen = strlen(r); ucslen = MOO_OBJ_GET_SIZE(arr->slot[j]);
moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* error check... */ bcslen = MOO_COUNTOF(bcs);
moo_convootobcstr (moo, ((moo_oop_char_t)arr->slot[j])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */
s = moo_makestring(moo, ucs, ucslen); bcs[bcslen] = '\0';
if (!s) dcArgPointer (dc, bcs);
{ j++;
dcFree (dc);
return MOO_PF_HARD_FAILURE; /* TODO: proper error h andling */
}
MOO_STACK_SETRET (moo, nargs, s);
break; break;
} }
default: default:
/* TODO: ERROR HANDLING */
moo_seterrnum (moo, MOO_EINVAL);
goto reterr;
break; break;
} }
dcFree (dc);
} }
if (i >= MOO_OBJ_GET_SIZE(sig)) goto call_void;
switch (((moo_oop_char_t)sig)->slot[i])
{
/* TODO: support more types... */
/* TODO: proper return value conversion */
case 'c':
{
char r = dcCallChar (dc, f);
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r));
break;
}
case 'i':
{
moo_oop_t r;
r = moo_ooitoint (moo, dcCallInt (dc, f));
if (!r) goto oops;
MOO_STACK_SETRET (moo, nargs, r);
break;
}
case 'l':
{
moo_oop_t r;
r = moo_ooitoint (moo, dcCallLong (dc, f));
if (!r) goto oops;
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 oops;
MOO_STACK_SETRET (moo, nargs, r);
break;
}
#endif
#if 0
case 'B': /* byte array */
{
}
#endif
case 's':
{
moo_oow_t bcslen, ucslen;
moo_ooch_t ucs[1024]; /* TOOD: buffer size... */
moo_oop_t s;
char* r = dcCallPointer (dc, f);
bcslen = strlen(r);
moo_convbtooochars (moo, r, &bcslen, ucs, &ucslen); /* error check... */
s = moo_makestring(moo, ucs, ucslen);
if (!s) goto oops;
MOO_STACK_SETRET (moo, nargs, s);
break;
}
default:
call_void:
dcCallVoid (dc, f);
MOO_STACK_SETRETTORCV (moo, nargs);
break;
}
dcFree (dc);
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
reterr: reterr:
if (dc) dcFree(dc);
MOO_STACK_SETRETTOERROR (moo, nargs); MOO_STACK_SETRETTOERROR (moo, nargs);
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
oops:
if (dc) dcFree(dc);
return MOO_PF_HARD_FAILURE;
#else #else
moo_seterrnum (moo, MOO_ENOIMPL); moo_seterrnum (moo, MOO_ENOIMPL);
MOO_STACK_SETRETTOERROR (moo, nargs); MOO_STACK_SETRETTOERROR (moo, nargs);