added more code for primitive module loading

This commit is contained in:
hyunghwan.chung 2015-10-13 14:51:04 +00:00
parent 8c963d919c
commit d367e2736b
7 changed files with 332 additions and 417 deletions

View File

@ -238,6 +238,8 @@
## ffi call: #puts withSig: 'i|s' withArgs: #('hello world').
ffi close."
self abc.
self abc.
self abc.
FFI isNil dump.
FFI notNil dump.

View File

@ -26,12 +26,9 @@
#include "stix-prv.h"
/* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */
#include <dynload.h> /* TODO: remove this. make dlXXX calls to callbacks */
#include <dyncall.h> /* TODO: remove this. make dyXXXX calls to callbacks */
/* TODO: context's stack overflow check in various part of this file */
/* TOOD: determine the right stack size */
#define CONTEXT_STACK_SIZE 96
@ -103,6 +100,7 @@
# define DBGOUT_EXEC_3(fmt,a1,a2,a3)
#endif
static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth)
{
stix_oop_context_t ctx;
@ -1029,27 +1027,19 @@ static int primitive_ffi_open (stix_t* stix, stix_ooi_t nargs)
return 0;
}
{ ///////////////////////
/* TODO: grow buffer */
stix_bch_t bcs[128];
stix_size_t ucslen, bcslen;
bcslen = STIX_COUNTOF(bcs);
ucslen = STIX_OBJ_GET_SIZE(arg);
if (stix_ucstoutf8 (((stix_oop_char_t)arg)->slot, &ucslen, bcs, &bcslen) <= -1)
if (!stix->vmprim.mod_open)
{
/* TODO: more info on error */
return 0;
}
bcs[bcslen] = '\0';
handle = dlLoadLibrary (bcs);
/* TODO: check null-termination... */
handle = stix->vmprim.mod_open (stix, ((stix_oop_char_t)arg)->slot);
if (!handle)
{
/* TODO: more info on error */
return 0;
}
} ///////////////////////
ACTIVE_STACK_POP (stix);
/* TODO: how to hold an address? as an integer???? or a byte array? */
@ -1079,7 +1069,7 @@ static int primitive_ffi_close (stix_t* stix, stix_ooi_t nargs)
ACTIVE_STACK_POP (stix);
handle = STIX_OOP_TO_SMINT(arg); /* TODO: how to store void* ??? */
dlFreeLibrary (handle);
if (stix->vmprim.mod_close) stix->vmprim.mod_close (stix, handle);
return 1;
}
@ -1275,29 +1265,16 @@ printf ("wrong function name...\n");
return 0;
}
{ ///////////////////////
/* TODO: grow buffer */
stix_bch_t bcs[128];
stix_size_t ucslen, bcslen;
bcslen = STIX_COUNTOF(bcs);
ucslen = STIX_OBJ_GET_SIZE(fun);
if (stix_ucstoutf8 (((stix_oop_char_t)fun)->slot, &ucslen, bcs, &bcslen) <= -1)
if (!stix->vmprim.mod_getsym)
{
/* TODO: more info on error */
return 0;
}
bcs[bcslen] = '\0';
printf ("FINDING SYMBOL %s\n", bcs);
sym = dlFindSymbol (STIX_OOP_TO_SMINT(hnd), bcs); // TODO: decode hnd properly.
sym = stix->vmprim.mod_getsym (stix, STIX_OOP_TO_SMINT(hnd), ((stix_oop_char_t)fun)->slot);
if (!sym)
{
/* TODO: more info on error */
return 0;
}
printf ("FOUND SYMBOL %p\n", sym);
} ///////////////////////
ACTIVE_STACK_POPS (stix, 2);
/* TODO: how to hold an address? as an integer???? or a byte array? */
@ -1343,8 +1320,9 @@ static primitive_t primitives[] =
{ 1, primitive_ffi_open, "ffiOpen" },
{ 1, primitive_ffi_close, "ffiClose" },
{ 3, primitive_ffi_call, "ffiCall" },
{ 2, primitive_ffi_getsym, "ffiGetSym" }
{ 2, primitive_ffi_getsym, "ffiGetSym" },
{ 3, primitive_ffi_call, "ffiCall" }
};
int stix_getprimno (stix_t* stix, const stix_ucs_t* name)
@ -1363,67 +1341,99 @@ int stix_getprimno (stix_t* stix, const stix_ucs_t* name)
return -1;
}
static stix_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name)
typedef struct stix_prim_mod_t stix_prim_mod_t;
typedef int (*stix_prim_mod_load_t) (
stix_t* stix,
stix_prim_mod_t* mod
);
typedef void* (*stix_prim_mod_query_t) (
stix_t* stix,
stix_prim_mod_t* mod,
const stix_uch_t* name
);
typedef void (*stix_prim_mod_unload_t) (
stix_t* stix,
stix_prim_mod_t* mod
);
struct stix_prim_mod_t
{
stix_prim_mod_load_t load;
stix_prim_mod_unload_t unload;
stix_prim_mod_query_t query;
};
struct stix_prim_mod_data_t
{
void* handle;
stix_prim_mod_t mod;
};
typedef struct stix_prim_mod_data_t stix_prim_mod_data_t;
static stix_prim_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name, stix_oow_t len)
{
stix_rbt_pair_t* pair;
stix_mod_data_t* mdp;
stix_cstr_t ea;
stix_prim_mod_data_t* mdp;
const stix_uch_t* sep;
stix_oow_t mod_name_len;
int n;
STIX_ASSERT (nsegs == 2);
sep = stix_findchar (name, len, '_');
STIX_ASSERT (sep != STIX_NULL);
mod_name_len = sep - name;
pair = stix_rbt_search (stix->modtab, segs[0].ptr, segs[0].len);
pair = stix_rbt_search (&stix->pmtable, name, mod_name_len);
if (pair)
{
mdp = (stix_mod_data_t*)STIX_RBT_VPTR(pair);
mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair);
}
else
{
stix_mod_data_t md;
stix_mod_load_t load = STIX_NULL;
stix_mod_spec_t spec;
stix_size_t buflen;
/*stix_char_t buf[64 + 15] = STIX_T("_stix_mod_");*/
stix_prim_mod_data_t md;
stix_prim_mod_load_t load = STIX_NULL;
/* maximum module name length is 64. 15 is decomposed to 13 + 1 + 1.
* 13 for _stix_mod_t
* 1 for _ at the end when stix_mod_xxx_ is attempted.
* 1 for the terminating '\0'
/* maximum module name length is STIX_MOD_NAME_LEN_MAX.
* 17 is decomposed to 15 + 1 + 1.
* 15 for _stix_prim_mod_.
* 1 for _ at the end when stix_prim_mod_xxx_ is attempted.
* 1 for the terminating '\0'.
*/
stix_char_t buf[64 + 15];
stix_uch_t buf[STIX_MOD_NAME_LEN_MAX + 17];
/* the terminating null isn't needed in buf here */
STIX_MEMCPY (buf, STIX_T("_stix_mod_"), STIX_SIZEOF(stix_char_t) * 13);
if (segs[0].len > STIX_COUNTOF(buf) - 15)
stix_copychars2 (buf, "_stix_prim_mod_", 15);
if (mod_name_len > STIX_COUNTOF(buf) - 17)
{
/* module name too long */
ea.ptr = segs[0].ptr;
ea.len = segs[0].len;
stix_seterror (stix, STIX_ESEGTL, &ea, STIX_NULL);
stix->errnum = STIX_EINVAL; /* TODO: change the error number to something more specific */
return STIX_NULL;
}
stix_copychars (&buf[15], name, mod_name_len);
buf[15 + mod_name_len] = '\0';
#if defined(STIX_ENABLE_STATIC_MODULE)
/* attempt to find a statically linked module */
/* TODO: binary search ... */
for (n = 0; n < STIX_COUNTOF(static_modtab); n++)
{
if (stix_strcmp (static_modtab[n].modname, segs[0].ptr) == 0)
if (stix_compucstr (static_modtab[n].modname, name) == 0)
{
load = static_modtab[n].modload;
break;
}
}
/*if (n >= STIX_COUNTOF(static_modtab))
if (n >= STIX_COUNTOF(static_modtab))
{
ea.ptr = segs[0].ptr;
ea.len = segs[0].len;
stix_seterror (stix, STIX_ENOENT, &ea, STIX_NULL);
stix->errnum = STIX_ENOENT;
return STIX_NULL;
}*/
}
if (load)
{
@ -1434,10 +1444,10 @@ static stix_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name)
/* i copy-insert 'md' into the table before calling 'load'.
* to pass the same address to load(), query(), etc */
pair = stix_rbt_insert (stix->modtab, segs[0].ptr, segs[0].len, &md, STIX_SIZEOF(md));
pair = stix_rbt_insert (stix->modtab, name, mod_name_len, &md, STIX_SIZEOF(md));
if (pair == STIX_NULL)
{
stix_seterrnum (stix, STIX_ENOMEM, STIX_NULL);
stix->errnum = STIX_ENOMEM;
return STIX_NULL;
}
@ -1453,79 +1463,49 @@ static stix_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name)
#endif
/* attempt to find an external module */
STIX_MEMSET (&spec, 0, STIX_SIZEOF(spec));
if (stix->opt.mod[0].len > 0)
spec.prefix = stix->opt.mod[0].ptr;
else spec.prefix = STIX_T(STIX_DEFAULT_MODPREFIX);
if (stix->opt.mod[1].len > 0)
spec.postfix = stix->opt.mod[1].ptr;
else spec.postfix = STIX_T(STIX_DEFAULT_MODPOSTFIX);
STIX_MEMSET (&md, 0, STIX_SIZEOF(md));
if (stix->prm.modopen && stix->prm.modsym && stix->prm.modclose)
if (stix->vmprim.mod_open && stix->vmprim.mod_getsym && stix->vmprim.mod_close)
{
spec.name = segs[0].ptr;
md.handle = stix->prm.modopen (stix, &spec);
md.handle = stix->vmprim.mod_open (stix, &buf[15]);
}
else md.handle = STIX_NULL;
if (md.handle == STIX_NULL)
{
ea.ptr = segs[0].ptr;
ea.len = segs[0].len;
stix_seterror (stix, STIX_ENOENT, &ea, STIX_NULL);
stix->errnum = STIX_ENOENT; /* TODO: be more descriptive about the error */
return STIX_NULL;
}
buflen = stix_strcpy (&buf[13], segs[0].ptr);
/* attempt stix_mod_xxx */
load = stix->prm.modsym (stix, md.handle, &buf[1]);
/* attempt to get stix_prim_mod_xxx */
load = stix->vmprim.mod_getsym (stix, md.handle, buf);
if (!load)
{
/* attempt _stix_mod_xxx */
load = stix->prm.modsym (stix, md.handle, &buf[0]);
if (!load)
{
/* attempt stix_mod_xxx_ */
buf[13 + buflen] = STIX_T('_');
buf[13 + buflen + 1] = STIX_T('\0');
load = stix->prm.modsym (stix, md.handle, &buf[1]);
if (!load)
{
ea.ptr = &buf[1];
ea.len = 12 + buflen;
stix_seterror (stix, STIX_ENOENT, &ea, STIX_NULL);
stix->prm.modclose (stix, md.handle);
stix->errnum = STIX_ENOENT; /* TODO: be more descriptive about the error */
stix->vmprim.mod_close (stix, md.handle);
return STIX_NULL;
}
}
}
/* i copy-insert 'md' into the table before calling 'load'.
* to pass the same address to load(), query(), etc */
pair = stix_rbt_insert (stix->modtab, segs[0].ptr, segs[0].len, &md, STIX_SIZEOF(md));
pair = stix_rbt_insert (&stix->pmtable, name, mod_name_len, &md, STIX_SIZEOF(md));
if (pair == STIX_NULL)
{
stix_seterrnum (stix, STIX_ENOMEM, STIX_NULL);
stix->prm.modclose (stix, md.handle);
stix->errnum = STIX_ENOMEM;
stix->vmprim.mod_close (stix, md.handle);
return STIX_NULL;
}
mdp = (stix_mod_data_t*)STIX_RBT_VPTR(pair);
if (load (&mdp->mod, stix) <= -1)
mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair);
if (load (stix, &mdp->mod) <= -1)
{
stix_rbt_delete (stix->modtab, segs[0].ptr, segs[0].len);
stix->prm.modclose (stix, mdp->handle);
stix_rbt_delete (&stix->pmtable, name, mod_name_len);
stix->vmprim.mod_close (stix, mdp->handle);
return STIX_NULL;
}
}
done:
n = mdp->mod.query (&mdp->mod, stix, segs[1].ptr, sym);
return (n <= -1)? STIX_NULL: &mdp->mod;
if (mdp->mod.query (stix, &mdp->mod, sep + 1) == STIX_NULL) return STIX_NULL;
return &mdp->mod;
}
/* ------------------------------------------------------------------------- */
@ -2161,9 +2141,11 @@ printf ("]\n");
STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(name));
STIX_ASSERT (STIX_CLASSOF(stix,name) == stix->_symbol);
handler = query_primitive_module (stix, ((stix_oop_char_t)name)->slot);
handler = query_primitive_module (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name));
if (handler)
{
int n;
stix_pushtmp (stix, (stix_oop_t*)&newmth);
n = handler (stix, b1);
stix_poptmp (stix);

View File

@ -29,8 +29,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <limits.h>
#include <dlfcn.h>
#if defined(_WIN32)
# define DEFAULT_MODPREFIX "stix-"
#elif defined(__OS2__)
# define DEFAULT_MODPREFIX "st-"
#elif defined(__DOS__)
# define DEFAULT_MODPREFIX "st-"
#else
# define DEFAULT_MODPREFIX "libstix-"
#endif
typedef struct xtn_t xtn_t;
struct xtn_t
{
@ -167,6 +181,63 @@ static stix_ssize_t input_handler (stix_t* stix, stix_io_cmd_t cmd, stix_io_arg_
}
}
static void* mod_open (stix_t* stix, const stix_uch_t* name)
{
/* TODO: support various platforms */
stix_bch_t buf[1024]; /* TODO: use a proper path buffer */
stix_size_t ucslen, bcslen;
stix_size_t len;
len = stix_copybcstr (buf, STIX_COUNTOF(buf), DEFAULT_MODPREFIX);
/* TODO: proper error checking and overflow checking */
ucslen = ~(stix_size_t)0;
bcslen = STIX_COUNTOF(buf) - len;
stix_ucstoutf8 (name, &ucslen, &buf[len], &bcslen);
printf ("MOD-OPENING %s\n", buf);
return dlopen (buf, RTLD_NOW);
}
static void mod_close (stix_t* stix, void* handle)
{
dlclose (handle);
}
static void* mod_getsym (stix_t* stix, void* handle, const stix_uch_t* name)
{
stix_bch_t buf[1024]; /* TODO: use a proper buffer. dynamically allocated if conversion result in too a large value */
stix_size_t ucslen, bcslen;
void* sym;
buf[0] = '_';
ucslen = ~(stix_size_t)0;
bcslen = STIX_COUNTOF(buf) - 2;
stix_ucstoutf8 (name, &ucslen, &buf[1], &bcslen);
printf ("MOD_GETSYM [%s]\n", &buf[1]);
sym = dlsym (handle, &buf[1]);
if (!sym)
{
printf ("MOD_GETSYM [%s]\n", &buf[0]);
sym = dlsym (handle, &buf[0]);
if (!sym)
{
buf[bcslen + 1] = '_';
buf[bcslen + 2] = '\0';
printf ("MOD_GETSYM [%s]\n", &buf[1]);
sym = dlsym (handle, &buf[1]);
if (!sym)
{
printf ("MOD_GETSYM [%s]\n", &buf[0]);
sym = dlsym (handle, &buf[0]);
}
}
}
return sym;
}
static char* syntax_error_msg[] =
{
"no error",
@ -233,6 +304,7 @@ int main (int argc, char* argv[])
xtn_t* xtn;
stix_ucs_t objname;
stix_ucs_t mthname;
stix_vmprim_t vmprim;
int i;
printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n",
@ -241,17 +313,6 @@ int main (int argc, char* argv[])
(unsigned long int)STIX_MAX_CLASSVARS,
(unsigned long int)STIX_MAX_CLASSINSTVARS);
{
stix_oop_t k;
k = STIX_OOP_FROM_SMINT(-1);
printf ("%ld %ld %ld %lX\n", (long int)STIX_OOP_TO_SMINT(k), (long int)STIX_SMINT_MIN, (long int)STIX_SMINT_MAX, (long)LONG_MIN);
k = STIX_OOP_FROM_SMINT(STIX_SMINT_MAX);
printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
k = STIX_OOP_FROM_SMINT(STIX_SMINT_MIN);
printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
}
#if !defined(macintosh)
if (argc < 2)
@ -261,18 +322,32 @@ printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
}
#endif
/*
{
stix_oop_t k;
stix_oow_t x;
printf ("%u\n", STIX_BITS_MAX(unsigned int, 5));
k = STIX_OOP_FROM_SMINT(-1);
printf ("%ld %ld %ld %lX\n", (long int)STIX_OOP_TO_SMINT(k), (long int)STIX_SMINT_MIN, (long int)STIX_SMINT_MAX, (long)LONG_MIN);
k = STIX_OOP_FROM_SMINT(STIX_SMINT_MAX);
printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
k = STIX_OOP_FROM_SMINT(STIX_SMINT_MIN);
printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
printf ("%u\n", STIX_BITS_MAX(unsigned int, 5));
x = STIX_CLASS_SPEC_MAKE (10, 1, STIX_OBJ_TYPE_CHAR);
printf ("%lu %lu %lu %lu\n", (unsigned long int)x, (unsigned long int)STIX_OOP_FROM_SMINT(x),
(unsigned long int)STIX_CLASS_SPEC_NAMED_INSTVAR(x),
(unsigned long int)STIX_CLASS_SPEC_INDEXED_TYPE(x));
}
}*/
stix = stix_open (&sys_mmgr, STIX_SIZEOF(xtn_t), 512000lu, STIX_NULL);
vmprim.mod_open = mod_open;
vmprim.mod_close = mod_close;
vmprim.mod_getsym = mod_getsym;
stix = stix_open (&sys_mmgr, STIX_SIZEOF(xtn_t), 512000lu, &vmprim, STIX_NULL);
if (!stix)
{
printf ("cannot open stix\n");
@ -283,9 +358,9 @@ printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
stix_oow_t tab_size;
tab_size = 5000;
stix_setoption (stix, STIX_DFL_SYMTAB_SIZE, &tab_size);
stix_setoption (stix, STIX_SYMTAB_SIZE, &tab_size);
tab_size = 5000;
stix_setoption (stix, STIX_DFL_SYSDIC_SIZE, &tab_size);
stix_setoption (stix, STIX_SYSDIC_SIZE, &tab_size);
}
{

View File

@ -60,6 +60,7 @@
#define STIX_MEMSET(dst,src,size) memset(dst,src,size)
#define STIX_MEMCPY(dst,src,size) memcpy(dst,src,size)
#define STIX_MEMMOVE(dst,src,size) memmove(dst,src,size)
#define STIX_MEMCMP(dst,src,size) memcmp(dst,src,size)
#define STIX_ASSERT(x) assert(x)
#define STIX_ALIGN(x,y) ((((x) + (y) - 1) / (y)) * (y))
@ -862,7 +863,17 @@ int stix_equalchars (
int stix_equalchars2 (
const stix_ucs_t* str1,
const char* str2
const stix_bch_t* str2
);
int stix_compucstr (
const stix_uch_t* str1,
const stix_uch_t* str2
);
int stix_compbcstr (
const stix_bch_t* str1,
const stix_bch_t* str2
);
void stix_copychars (
@ -871,12 +882,30 @@ void stix_copychars (
stix_size_t len
);
void stix_copychars2 (
stix_uch_t* dst,
const stix_bch_t* src,
stix_size_t len
);
stix_uch_t* stix_findchar (
const stix_uch_t* ptr,
stix_size_t len,
stix_uch_t c
);
stix_size_t stix_copyucstr (
stix_uch_t* dst,
stix_size_t len,
const stix_uch_t* src
);
stix_size_t stix_copybcstr (
stix_bch_t* dst,
stix_size_t len,
const stix_bch_t* src
);
/* ========================================================================= */
/* gc.c */
/* ========================================================================= */

View File

@ -27,7 +27,7 @@
#include "stix-prv.h"
stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, stix_errnum_t* errnum)
stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, const stix_vmprim_t* vmprim, stix_errnum_t* errnum)
{
stix_t* stix;
@ -37,7 +37,7 @@ stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize,
stix = STIX_MMGR_ALLOC (mmgr, STIX_SIZEOF(*stix) + xtnsize);
if (stix)
{
if (stix_init(stix, mmgr, heapsize) <= -1)
if (stix_init(stix, mmgr, heapsize, vmprim) <= -1)
{
if (errnum) *errnum = stix->errnum;
STIX_MMGR_FREE (mmgr, stix);
@ -56,10 +56,11 @@ void stix_close (stix_t* stix)
STIX_MMGR_FREE (stix->mmgr, stix);
}
int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz)
int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz, const stix_vmprim_t* vmprim)
{
STIX_MEMSET (stix, 0, STIX_SIZEOF(*stix));
stix->mmgr = mmgr;
stix->vmprim = *vmprim;
/*stix->permheap = stix_makeheap (stix, what is the best size???);
if (!stix->curheap) goto oops; */
@ -68,6 +69,8 @@ int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz)
stix->newheap = stix_makeheap (stix, heapsz);
if (!stix->newheap) goto oops;
if (stix_rbt_init (&stix->pmtable, mmgr, STIX_SIZEOF(stix_uch_t), 1) <= -1) goto oops;
stix_rbt_setstyle (&stix->pmtable, stix_getrbtstyle(STIX_RBT_STYLE_INLINE_COPIERS));
return 0;
oops:
@ -86,11 +89,12 @@ void stix_fini (stix_t* stix)
if (cb->fini) cb->fini (stix);
}
stix_rbt_fini (&stix->pmtable);
stix_killheap (stix, stix->newheap);
stix_killheap (stix, stix->curheap);
stix_killheap (stix, stix->permheap);
/* deregister all callbacks */
while (stix->cblist) stix_deregcb (stix, stix->cblist);
}
@ -124,11 +128,13 @@ int stix_setoption (stix_t* stix, stix_option_t id, const void* value)
stix->option.trait = *(const int*)value;
return 0;
case STIX_DFL_SYMTAB_SIZE:
case STIX_SYMTAB_SIZE:
stix->option.dfl_symtab_size = *(stix_oow_t*)value;
return 0;
case STIX_DFL_SYSDIC_SIZE:
case STIX_SYSDIC_SIZE:
stix->option.dfl_sysdic_size = *(stix_oow_t*)value;
return 0;
}
stix->errnum = STIX_EINVAL;
@ -143,10 +149,10 @@ int stix_getoption (stix_t* stix, stix_option_t id, void* value)
*(int*)value = stix->option.trait;
return 0;
case STIX_DFL_SYMTAB_SIZE:
case STIX_SYMTAB_SIZE:
*(stix_oow_t*)value = stix->option.dfl_symtab_size;
case STIX_DFL_SYSDIC_SIZE:
case STIX_SYSDIC_SIZE:
*(stix_oow_t*)value = stix->option.dfl_sysdic_size;
};
@ -214,7 +220,7 @@ int stix_equalchars (const stix_uch_t* str1, const stix_uch_t* str2, stix_size_t
return 1;
}
int stix_equalchars2 (const stix_ucs_t* str1, const char* str2)
int stix_equalchars2 (const stix_ucs_t* str1, const stix_bch_t* str2)
{
const stix_uch_t* ptr, * end;
@ -229,12 +235,72 @@ int stix_equalchars2 (const stix_ucs_t* str1, const char* str2)
return ptr >= end && *str2 == '\0';
}
int stix_compucstr (const stix_uch_t* str1, const stix_uch_t* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0') return 0;
str1++, str2++;
}
return (*str1 > *str2)? 1: -1;
}
int stix_compbcstr (const stix_bch_t* str1, const stix_bch_t* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0') return 0;
str1++, str2++;
}
return (*str1 > *str2)? 1: -1;
}
void stix_copychars (stix_uch_t* dst, const stix_uch_t* src, stix_size_t len)
{
stix_size_t i;
for (i = 0; i < len; i++) dst[i] = src[i];
}
void stix_copychars2 (stix_uch_t* dst, const stix_bch_t* src, stix_size_t len)
{
stix_size_t i;
for (i = 0; i < len; i++) dst[i] = src[i];
}
stix_size_t stix_copyucstr (stix_uch_t* dst, stix_size_t len, const stix_uch_t* src)
{
stix_uch_t* p, * p2;
p = dst; p2 = dst + len - 1;
while (p < p2)
{
if (*src == '\0') break;
*p++ = *src++;
}
if (len > 0) *p = '\0';
return p - dst;
}
stix_size_t stix_copybcstr (stix_bch_t* dst, stix_size_t len, const stix_bch_t* src)
{
stix_bch_t* p, * p2;
p = dst; p2 = dst + len - 1;
while (p < p2)
{
if (*src == '\0') break;
*p++ = *src++;
}
if (len > 0) *p = '\0';
return p - dst;
}
stix_uch_t* stix_findchar (const stix_uch_t* ptr, stix_size_t len, stix_uch_t c)
{
const stix_uch_t* end;

View File

@ -27,252 +27,12 @@
#ifndef _STIX_H_
#define _STIX_H_
#include "stix-cmn.h"
#include "stix-rbt.h"
/* TODO: move this macro out to the build files.... */
#define STIX_INCLUDE_COMPILER
/* =========================================================================
* PRIMITIVE TYPE DEFINTIONS
* ========================================================================= */
/* TODO: define these types and macros using autoconf */
typedef unsigned char stix_uint8_t;
typedef signed char stix_int8_t;
typedef unsigned short int stix_uint16_t;
typedef signed short int stix_int16_t;
#if defined(__MSDOS__)
typedef unsigned long int stix_uint32_t;
typedef signed long int stix_int32_t;
#else
typedef unsigned int stix_uint32_t;
typedef signed int stix_int32_t;
#endif
#if defined(_WIN64)
typedef unsigned __int64 stix_uintptr_t;
typedef signed __int64 stix_intptr_t;
typedef unsigned __int64 stix_size_t;
typedef signed __int64 stix_ssize_t;
#else
typedef unsigned long int stix_uintptr_t;
typedef signed long int stix_intptr_t;
typedef unsigned long int stix_size_t;
typedef signed long int stix_ssize_t;
#endif
typedef stix_uint8_t stix_byte_t;
typedef stix_uint16_t stix_uch_t; /* TODO ... wchar_t??? */
typedef stix_int32_t stix_uci_t;
typedef char stix_bch_t;
struct stix_ucs_t
{
stix_uch_t* ptr;
stix_size_t len;
};
typedef struct stix_ucs_t stix_ucs_t;
/* =========================================================================
* PRIMITIVE MACROS
* ========================================================================= */
#define STIX_UCI_EOF ((stix_uci_t)-1)
#define STIX_UCI_NL ((stix_uci_t)'\n')
#define STIX_SIZEOF(x) (sizeof(x))
#define STIX_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
/**
* The STIX_OFFSETOF() macro returns the offset of a field from the beginning
* of a structure.
*/
#define STIX_OFFSETOF(type,member) ((stix_uintptr_t)&((type*)0)->member)
/**
* The STIX_ALIGNOF() macro returns the alignment size of a structure.
* Note that this macro may not work reliably depending on the type given.
*/
#define STIX_ALIGNOF(type) STIX_OFFSETOF(struct { stix_uint8_t d1; type d2; }, d2)
/*(sizeof(struct { stix_uint8_t d1; type d2; }) - sizeof(type))*/
#if defined(__cplusplus)
# if (__cplusplus >= 201103L) /* C++11 */
# define STIX_NULL nullptr
# else
# define STIX_NULL (0)
# endif
#else
# define STIX_NULL ((void*)0)
#endif
/* make a low bit mask that can mask off low n bits*/
#define STIX_LBMASK(type,n) (~(~((type)0) << (n)))
/* get 'length' bits starting from the bit at the 'offset' */
#define STIX_GETBITS(type,value,offset,length) \
((((type)(value)) >> (offset)) & STIX_LBMASK(type,length))
#define STIX_SETBITS(type,value,offset,length,bits) \
(value = (((type)(value)) | (((bits) & STIX_LBMASK(type,length)) << (offset))))
/**
* The STIX_BITS_MAX() macros calculates the maximum value that the 'nbits'
* bits of an unsigned integer of the given 'type' can hold.
* \code
* printf ("%u", STIX_BITS_MAX(unsigned int, 5));
* \endcode
*/
/*#define STIX_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/
#define STIX_BITS_MAX(type,nbits) ((~(type)0) >> (STIX_SIZEOF(type) * 8 - (nbits)))
/* =========================================================================
* POINTER MANIPULATION MACROS
* ========================================================================= */
#if defined(__MSDOS__)
# define STIX_INCPTR(type,base,inc) (((type __huge*)base) + (inc))
# define STIX_DECPTR(type,base,inc) (((type __huge*)base) - (inc))
# define STIX_GTPTR(type,ptr1,ptr2) (((type __huge*)ptr1) > ((type __huge*)ptr2))
# define STIX_GEPTR(type,ptr1,ptr2) (((type __huge*)ptr1) >= ((type __huge*)ptr2))
# define STIX_LTPTR(type,ptr1,ptr2) (((type __huge*)ptr1) < ((type __huge*)ptr2))
# define STIX_LEPTR(type,ptr1,ptr2) (((type __huge*)ptr1) <= ((type __huge*)ptr2))
# define STIX_EQPTR(type,ptr1,ptr2) (((type __huge*)ptr1) == ((type __huge*)ptr2))
# define STIX_SUBPTR(type,ptr1,ptr2) (((type __huge*)ptr1) - ((type __huge*)ptr2))
#else
# define STIX_INCPTR(type,base,inc) (((type*)base) + (inc))
# define STIX_DECPTR(type,base,inc) (((type*)base) - (inc))
# define STIX_GTPTR(type,ptr1,ptr2) (((type*)ptr1) > ((type*)ptr2))
# define STIX_GEPTR(type,ptr1,ptr2) (((type*)ptr1) >= ((type*)ptr2))
# define STIX_LTPTR(type,ptr1,ptr2) (((type*)ptr1) < ((type*)ptr2))
# define STIX_LEPTR(type,ptr1,ptr2) (((type*)ptr1) <= ((type*)ptr2))
# define STIX_EQPTR(type,ptr1,ptr2) (((type*)ptr1) == ((type*)ptr2))
# define STIX_SUBPTR(type,ptr1,ptr2) (((type*)ptr1) - ((type*)ptr2))
#endif
/* =========================================================================
* MMGR
* ========================================================================= */
typedef struct stix_mmgr_t stix_mmgr_t;
/**
* allocate a memory chunk of the size \a n.
* \return pointer to a memory chunk on success, #STIX_NULL on failure.
*/
typedef void* (*stix_mmgr_alloc_t) (stix_mmgr_t* mmgr, stix_size_t n);
/**
* resize a memory chunk pointed to by \a ptr to the size \a n.
* \return pointer to a memory chunk on success, #STIX_NULL on failure.
*/
typedef void* (*stix_mmgr_realloc_t) (stix_mmgr_t* mmgr, void* ptr, stix_size_t n);
/**
* free a memory chunk pointed to by \a ptr.
*/
typedef void (*stix_mmgr_free_t) (stix_mmgr_t* mmgr, void* ptr);
/**
* The stix_mmgr_t type defines the memory management interface.
* As the type is merely a structure, it is just used as a single container
* for memory management functions with a pointer to user-defined data.
* The user-defined data pointer \a ctx is passed to each memory management
* function whenever it is called. You can allocate, reallocate, and free
* a memory chunk.
*
* For example, a stix_xxx_open() function accepts a pointer of the stix_mmgr_t
* type and the xxx object uses it to manage dynamic data within the object.
*/
struct stix_mmgr_t
{
stix_mmgr_alloc_t alloc; /**< allocation function */
stix_mmgr_realloc_t realloc; /**< resizing function */
stix_mmgr_free_t free; /**< disposal function */
void* ctx; /**< user-defined data pointer */
};
/**
* The STIX_MMGR_ALLOC() macro allocates a memory block of the \a size bytes
* using the \a mmgr memory manager.
*/
#define STIX_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size))
/**
* The STIX_MMGR_REALLOC() macro resizes a memory block pointed to by \a ptr
* to the \a size bytes using the \a mmgr memory manager.
*/
#define STIX_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size))
/**
* The STIX_MMGR_FREE() macro deallocates the memory block pointed to by \a ptr.
*/
#define STIX_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr))
/* =========================================================================
* CMGR
* =========================================================================*/
typedef struct stix_cmgr_t stix_cmgr_t;
typedef stix_size_t (*stix_cmgr_bctouc_t) (
const stix_bch_t* mb,
stix_size_t size,
stix_uch_t* wc
);
typedef stix_size_t (*stix_cmgr_uctobc_t) (
stix_uch_t wc,
stix_bch_t* mb,
stix_size_t size
);
/**
* The stix_cmgr_t type defines the character-level interface to
* multibyte/wide-character conversion. This interface doesn't
* provide any facility to store conversion state in a context
* independent manner. This leads to the limitation that it can
* handle a stateless multibyte encoding only.
*/
struct stix_cmgr_t
{
stix_cmgr_bctouc_t bctouc;
stix_cmgr_uctobc_t uctobc;
};
/* =========================================================================
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER
* =========================================================================*/
#if defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__))
# define STIX_IMPORT __declspec(dllimport)
# define STIX_EXPORT __declspec(dllexport)
# define STIX_PRIVATE
#elif defined(__GNUC__) && (__GNUC__>=4)
# define STIX_IMPORT __attribute__((visibility("default")))
# define STIX_EXPORT __attribute__((visibility("default")))
# define STIX_PRIVATE __attribute__((visibility("hidden")))
/*# define STIX_PRIVATE __attribute__((visibility("internal")))*/
#else
# define STIX_IMPORT
# define STIX_EXPORT
# define STIX_PRIVATE
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
# define STIX_INLINE inline
# define STIX_HAVE_INLINE
#elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
/* gcc disables inline when -std=c89 or -ansi is used.
* so use __inline__ supported by gcc regardless of the options */
# define STIX_INLINE /*extern*/ __inline__
# define STIX_HAVE_INLINE
#else
# define STIX_INLINE
# undef STIX_HAVE_INLINE
#endif
/* ========================================================================== */
/**
@ -301,8 +61,8 @@ typedef enum stix_errnum_t stix_errnum_t;
enum stix_option_t
{
STIX_TRAIT,
STIX_DFL_SYMTAB_SIZE,
STIX_DFL_SYSDIC_SIZE
STIX_SYMTAB_SIZE, /* default system table size */
STIX_SYSDIC_SIZE /* default system dictionary size */
};
typedef enum stix_option_t stix_option_t;
@ -741,33 +501,32 @@ struct stix_heap_t
typedef struct stix_t stix_t;
/* =========================================================================
* MODULE MANIPULATION
* VIRTUAL MACHINE PRIMITIVES
* ========================================================================= */
enum stix_mod_cmd_t
#define STIX_MOD_PREFIX_LEN_MAX 30
#define STIX_MOD_POSTFIX_LEN_MAX 30
#define STIX_MOD_NAME_LEN_MAX 60
struct stix_mod_spec_t
{
STIX_MOD_OPEN,
STIX_MOD_CLOSE,
STIX_MOD_READ
const stix_uch_t prefix[STIX_MOD_PREFIX_LEN_MAX];
const stix_uch_t postfix[STIX_MOD_POSTFIX_LEN_MAX];
const stix_uch_t name[STIX_MOD_NAME_LEN_MAX];
};
typedef enum stix_mod_cmd_t stix_mod_cmd_t;
typedef struct stix_mod_spec_t stix_mod_spec_t;
struct stix_mod_arg_t
typedef void* (*stix_mod_open_t) (stix_t* stix, const stix_uch_t* name);
typedef void (*stix_mod_close_t) (stix_t* stix, void* handle);
typedef void* (*stix_mod_getsym_t) (stix_t* stix, void* handle, const stix_uch_t* name);
struct stix_vmprim_t
{
/* [INPUT] */
const stix_uch_t* prefix;
const stix_uch_t* postfix;
const stix_uch_t* name;
/* [OUTPUT] */
void* handle;
stix_mod_open_t mod_open;
stix_mod_close_t mod_close;
stix_mod_getsym_t mod_getsym;
};
typedef struct stix_mod_arg_t stix_mod_arg_t;
typedef int (*stix_mod_impl_t) (
stix_t* stix,
stix_mod_cmd_t cmd,
stix_mod_arg_t* arg
);
typedef struct stix_vmprim_t stix_vmprim_t;
/* =========================================================================
* IO MANIPULATION
@ -806,10 +565,14 @@ struct stix_t
int trait;
stix_oow_t dfl_symtab_size;
stix_oow_t dfl_sysdic_size;
stix_ucs_t dfl_mod_prefix[STIX_MOD_PREFIX_LEN_MAX + 1];
stix_ucs_t dfl_mod_postfix[STIX_MOD_POSTFIX_LEN_MAX + 1];
} option;
stix_cb_t* cblist;
stix_vmprim_t vmprim;
stix_cb_t* cblist;
stix_rbt_t pmtable; /* primitive module table */
/* ========================= */
stix_heap_t* permheap; /* TODO: put kernel objects to here */
@ -878,6 +641,7 @@ STIX_EXPORT stix_t* stix_open (
stix_mmgr_t* mmgr,
stix_size_t xtnsize,
stix_size_t heapsize,
const stix_vmprim_t* vmprim,
stix_errnum_t* errnum
);
@ -888,7 +652,8 @@ STIX_EXPORT void stix_close (
STIX_EXPORT int stix_init (
stix_t* vm,
stix_mmgr_t* mmgr,
stix_size_t heapsz
stix_size_t heapsize,
const stix_vmprim_t* vmprim
);
STIX_EXPORT void stix_fini (

View File

@ -482,9 +482,7 @@ static stix_cmgr_t utf8_cmgr =
stix_uctoutf8
};
int stix_utf8toucs (
const stix_bch_t* bcs, stix_size_t* bcslen,
stix_uch_t* ucs, stix_size_t* ucslen)
int stix_utf8toucs (const stix_bch_t* bcs, stix_size_t* bcslen, stix_uch_t* ucs, stix_size_t* ucslen)
{
if (*bcslen == ~(stix_size_t)0)
{
@ -498,9 +496,7 @@ int stix_utf8toucs (
}
}
int stix_ucstoutf8 (
const stix_uch_t* ucs, stix_size_t *ucslen,
stix_bch_t* bcs, stix_size_t* bcslen)
int stix_ucstoutf8 (const stix_uch_t* ucs, stix_size_t *ucslen, stix_bch_t* bcs, stix_size_t* bcslen)
{
if (*ucslen == ~(stix_size_t)0)
{