diff --git a/stix/kernel/test-005.st b/stix/kernel/test-005.st index a145065..c5c2843 100644 --- a/stix/kernel/test-005.st +++ b/stix/kernel/test-005.st @@ -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. diff --git a/stix/lib/exec.c b/stix/lib/exec.c index c98ff71..cb78b36 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -26,12 +26,9 @@ #include "stix-prv.h" - /* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ -#include /* TODO: remove this. make dlXXX calls to callbacks */ #include /* 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); - if (!handle) +/* 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. - if (!sym) + 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); - return STIX_NULL; - } - } + 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); diff --git a/stix/lib/main.c b/stix/lib/main.c index a55b479..ee3f366 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -29,8 +29,22 @@ #include #include #include +#include #include +#include + +#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); } { diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 90dd457..a131489 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -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)) @@ -857,12 +858,22 @@ stix_size_t stix_hashchars ( int stix_equalchars ( const stix_uch_t* str1, const stix_uch_t* str2, - stix_size_t len + stix_size_t len ); 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 */ /* ========================================================================= */ diff --git a/stix/lib/stix.c b/stix/lib/stix.c index cf7fb85..48ffc42 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -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; diff --git a/stix/lib/stix.h b/stix/lib/stix.h index e325b7c..709f438 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -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 */ @@ -875,10 +638,11 @@ extern "C" { #endif STIX_EXPORT stix_t* stix_open ( - stix_mmgr_t* mmgr, - stix_size_t xtnsize, - stix_size_t heapsize, - stix_errnum_t* errnum + stix_mmgr_t* mmgr, + stix_size_t xtnsize, + stix_size_t heapsize, + const stix_vmprim_t* vmprim, + stix_errnum_t* errnum ); STIX_EXPORT void stix_close ( @@ -886,9 +650,10 @@ STIX_EXPORT void stix_close ( ); STIX_EXPORT int stix_init ( - stix_t* vm, - stix_mmgr_t* mmgr, - stix_size_t heapsz + stix_t* vm, + stix_mmgr_t* mmgr, + stix_size_t heapsize, + const stix_vmprim_t* vmprim ); STIX_EXPORT void stix_fini ( diff --git a/stix/lib/utf8.c b/stix/lib/utf8.c index 8b19f44..4464be9 100644 --- a/stix/lib/utf8.c +++ b/stix/lib/utf8.c @@ -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) {