added more code to ffi
This commit is contained in:
parent
f23486468d
commit
d130ec02ec
@ -88,7 +88,8 @@ 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.
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
332
moo/mod/ffi.c
332
moo/mod/ffi.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user