From 447670aba8e4b106e9427b0a2c538be42428cca5 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 31 Mar 2017 14:21:22 +0000 Subject: [PATCH] implemented more prechecks including the existence of the primitive function handler and the number of supported arguments when compiling primitive method defintions --- moo/kernel/FFI.moo | 2 +- moo/kernel/Mill.moo | 5 ++- moo/kernel/generr.moo | 31 ++++++-------- moo/lib/comp.c | 95 +++++++++++++++++++++++++++++++++---------- moo/lib/err.c | 21 +++++----- moo/lib/exec.c | 12 +++++- moo/lib/moo-utl.h | 16 ++++++++ moo/lib/moo.c | 14 +++---- moo/lib/moo.h | 13 +++--- moo/lib/utl.c | 19 +++++++++ moo/mod/console.c | 4 +- moo/mod/ffi.c | 4 +- moo/mod/stdio.c | 4 +- moo/mod/x11.c | 12 +++--- 14 files changed, 172 insertions(+), 80 deletions(-) diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo index ee89856..93aca2d 100644 --- a/moo/kernel/FFI.moo +++ b/moo/kernel/FFI.moo @@ -1,7 +1,7 @@ class _FFI(Object) from 'ffi' { method(#primitive) open(name). - method(#primitive) close(). + method(#primitive) close. method(#primitive) getsym(name). (* TODO: make call variadic? method(#primitive,#variadic) call (func, sig). *) diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index b082c5c..7f059ca 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -114,8 +114,7 @@ class MyObject(Object) method(#class) main_xx { |a k| - - + 'BEGINNING OF main...........' dump. a := if ([System logNl: 'xxxx'. 'abcd' == 'bcde'. false] value) @@ -270,6 +269,8 @@ class MyObject(Object) { |a i| +###self main_xx. + a := 100. ## PROBLEM: the following double loop will exhaust the stack (* diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index c3ceadc..e1de135 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -99,6 +99,7 @@ class MyObject(Object) 'too large array expression' 'wrong primitive function number' 'wrong primitive function identifier' + 'wrong primitive function argument definition' 'wrong module name' '#include error' 'wrong namespace name' @@ -130,18 +131,15 @@ class MyObject(Object) ]. - f puts: S'static moo_ooch_t* '. - f puts: name. - f puts: S'[] =\n{\n'. + f puts(S'static moo_ooch_t* ', name, S'[] =\n{\n'). 0 to: c do: [:i | - ((i rem: 8) = 0) ifTrue: [ f putc: C'\t' ]. - f puts: prefix. - f puts: (i asString). - (i = c) ifFalse: [f puts: S',' ]. - (((i + 1) rem: 8) = 0) ifTrue: [ f putc: C'\n' ] ifFalse: [ f putc: C' ' ]. + ((i rem: 8) = 0) ifTrue: [ f putc(C'\t') ]. + f puts(prefix, (i asString)). + (i = c) ifFalse: [f puts(S',') ]. + (((i + 1) rem: 8) = 0) ifTrue: [ f putc(C'\n') ] ifFalse: [ f putc(C' ') ]. ]. - (((c + 1) rem: 8) = 0) ifFalse: [ f putc: C'\n' ]. - f puts: S'};\n'. + (((c + 1) rem: 8) = 0) ifFalse: [ f putc(C'\n') ]. + f puts(S'};\n'). } method(#class) printString: s prefix: prefix index: index on: f @@ -149,18 +147,13 @@ class MyObject(Object) | c | c := s size - 1. - f puts: 'static moo_ooch_t '. - f puts: prefix. - f puts: index asString. - f puts: '[] = {'. + f puts('static moo_ooch_t ', prefix, index asString, '[] = {'). 0 to: c do: [:i | - f putc: $'. - f putc: (s at: i). - f putc: $'. - (i = c) ifFalse: [f putc: $, ]. + f putc($', (s at: i), $'). + (i = c) ifFalse: [f putc($,) ]. ]. - f puts: S',\'\\0\'};\n'. + f puts(S',\'\\0\'};\n'). } } diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 7ddc7cc..4004e0f 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -365,7 +365,7 @@ static void set_syntax_error (moo_t* moo, moo_synerrnum_t num, const moo_ioloc_t } } -static int copy_string_to (moo_t* moo, const moo_oocs_t* src, moo_oocs_t* dst, moo_oow_t* dst_capa, int append, moo_ooch_t add_delim) +static int copy_string_to (moo_t* moo, const moo_oocs_t* src, moo_oocs_t* dst, moo_oow_t* dst_capa, int append, moo_ooch_t delim_char) { moo_oow_t len, pos; @@ -373,7 +373,7 @@ static int copy_string_to (moo_t* moo, const moo_oocs_t* src, moo_oocs_t* dst, m { pos = dst->len; len = dst->len + src->len; - if (add_delim != '\0') len++; + if (delim_char != '\0') len++; } else { @@ -395,7 +395,7 @@ static int copy_string_to (moo_t* moo, const moo_oocs_t* src, moo_oocs_t* dst, m *dst_capa = capa; } - if (append && add_delim) dst->ptr[pos++] = add_delim; + if (append && delim_char) dst->ptr[pos++] = delim_char; moo_copyoochars (&dst->ptr[pos], src->ptr, src->len); dst->len = len; return 0; @@ -2478,7 +2478,7 @@ static int add_string_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* ind return add_literal (moo, lit, index); } -static int add_symbol_literal (moo_t* moo, const moo_oocs_t* str, int offset, moo_oow_t* index) +static int add_symbol_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t offset, moo_oow_t* index) { moo_oop_t tmp; @@ -3391,6 +3391,8 @@ static int compile_method_primitive (moo_t* moo) ptr++; } +/* TODO: check if the number points to one of the internal primitive function */ + moo->c->mth.pfnum = pfnum; break; @@ -3409,29 +3411,55 @@ static int compile_method_primitive (moo_t* moo) /* a built-in primitive function is not found * check if it is a primitive function identifier */ moo_oow_t lit_idx; + moo_pfbase_t* pfbase; - if (moo_findoochar (tptr, tlen, '.') && - add_symbol_literal(moo, TOKEN_NAME(moo), 1, &lit_idx) >= 0 && - MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx)) + if (!moo_rfindoochar (tptr, tlen, '.')) { - /* external named primitive containing a period. */ - moo->c->mth.pftype = PFTYPE_NAMED; - moo->c->mth.pfnum = lit_idx; - break; + /* wrong primitive functio identifier */ + set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; } - /* wrong primitive number */ - set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + /* external named primitive containing a period. */ + + /* perform some sanity checks. see compile_method_definition() for similar checks */ + pfbase = moo_querymod (moo, tptr, tlen); + if (!pfbase) + { + MOO_DEBUG2 (moo, "Cannot find module primitive function - %.*js\n", tlen, tptr); + set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (moo->c->mth.tmpr_nargs < pfbase->minargs || moo->c->mth.tmpr_nargs > pfbase->maxargs) + { + MOO_DEBUG5 (moo, "Unsupported argument count in primitive method definition of %.*js - %zd-%zd expected, %zd specified\n", + tlen, tptr, pfbase->minargs, pfbase->maxargs, moo->c->mth.tmpr_nargs); + set_syntax_error (moo, MOO_SYNERR_PFARGDEFINVAL, &moo->c->mth.name_loc, &moo->c->mth.name); + return -1; + } + + if (add_symbol_literal(moo, TOKEN_NAME(moo), 1, &lit_idx) <= -1) return -1; + + /* the primitive definition is placed at the very beginning of a method defintion. + * so the index to the symbol registered should be very small like 0 */ + MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx)); + + moo->c->mth.pftype = PFTYPE_NAMED; + moo->c->mth.pfnum = lit_idx; } else if (!MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(pfnum)) { set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); return -1; } + else + { + /* TODO: check argument count for this primitive ... */ + moo->c->mth.pftype = PFTYPE_NUMBERED; + moo->c->mth.pfnum = pfnum; + } - moo->c->mth.pftype = PFTYPE_NUMBERED; - moo->c->mth.pfnum = pfnum; break; } @@ -5877,6 +5905,9 @@ static int compile_method_definition (moo_t* moo) if (moo->c->cls.self_oop->modname == moo->_nil) { + /* no module name specified in the class definition using 'from'. + * it's a builtin primitive function */ + moo_oow_t savedlen; moo_ooi_t pfnum; @@ -5895,13 +5926,14 @@ static int compile_method_definition (moo_t* moo) pfnum = moo_getpfnum (moo, &moo->c->cls.modname.ptr[savedlen], moo->c->cls.modname.len - savedlen); if (pfnum <= -1 || !MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(pfnum)) { - MOO_DEBUG2 (moo, "Cannot find intrinsic primitive handler - %.*js\n", + MOO_DEBUG2 (moo, "Cannot find intrinsic primitive function - %.*js\n", moo->c->cls.modname.len - savedlen, &moo->c->cls.modname.ptr[savedlen]); - moo->c->cls.modname.len = savedlen; set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, &moo->c->mth.name_loc, &moo->c->mth.name); + moo->c->cls.modname.len = savedlen; return -1; } +/* TODO: check argumetns... */ moo->c->cls.modname.len = savedlen; moo->c->mth.pftype = PFTYPE_NUMBERED; @@ -5911,6 +5943,7 @@ static int compile_method_definition (moo_t* moo) { moo_oow_t litidx, savedlen; moo_oocs_t tmp; + moo_pfbase_t* pfbase; /* combine the module name and the method name delimited by a period * when doing it, let me reuse the cls.modname buffer and restore it @@ -5921,9 +5954,6 @@ static int compile_method_definition (moo_t* moo) tmp.ptr = MOO_OBJ_GET_CHAR_SLOT(moo->c->cls.self_oop->modname); tmp.len = MOO_OBJ_GET_SIZE(moo->c->cls.self_oop->modname); - /* TODO: i can check if the primitive method is available at compile time by querying the module. - * do the check depending on the compiler option */ - if (copy_string_to (moo, &tmp, &moo->c->cls.modname, &moo->c->cls.modname_capa, 1, '\0') <= -1 || copy_string_to (moo, &moo->c->mth.name, &moo->c->cls.modname, &moo->c->cls.modname_capa, 1, '.') <= -1 || add_symbol_literal(moo, &moo->c->cls.modname, savedlen, &litidx) <= -1) @@ -5932,8 +5962,29 @@ static int compile_method_definition (moo_t* moo) return -1; } + /* check if the primitive function exists at the compile time and perform some checks. + * see compile_method_primitive() for similar checks */ + pfbase = moo_querymod (moo, &moo->c->cls.modname.ptr[savedlen], moo->c->cls.modname.len - savedlen); + if (!pfbase) + { + MOO_DEBUG2 (moo, "Cannot find module primitive function - %.*js\n", + moo->c->cls.modname.len - savedlen, &moo->c->cls.modname.ptr[savedlen]); + set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, &moo->c->mth.name_loc, &moo->c->mth.name); + moo->c->cls.modname.len = savedlen; + return -1; + } + + if (moo->c->mth.tmpr_nargs < pfbase->minargs || moo->c->mth.tmpr_nargs > pfbase->maxargs) + { + MOO_DEBUG5 (moo, "Unsupported argument count in primitive method definition of %.*js - %zd-%zd expected, %zd specified\n", + moo->c->cls.modname.len - savedlen, &moo->c->cls.modname.ptr[savedlen], + pfbase->minargs, pfbase->maxargs, moo->c->mth.tmpr_nargs); + set_syntax_error (moo, MOO_SYNERR_PFARGDEFINVAL, &moo->c->mth.name_loc, &moo->c->mth.name); + moo->c->cls.modname.len = savedlen; + return -1; + } + moo->c->cls.modname.len = savedlen; - /* the symbol added must be the first literal to the current method. * so this condition must be true. */ MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(litidx)); diff --git a/moo/lib/err.c b/moo/lib/err.c index d65076f..582c892 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -125,15 +125,16 @@ static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','l','a','r','g','e',' ','b', static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; static moo_ooch_t synerrstr_55[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; static moo_ooch_t synerrstr_56[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_58[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; -static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_61[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_62[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_63[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; -static moo_ooch_t synerrstr_64[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_65[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; +static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_59[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; +static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_61[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_62[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_63[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_64[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; +static moo_ooch_t synerrstr_65[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_66[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t* synerrstr[] = { synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, @@ -144,7 +145,7 @@ static moo_ooch_t* synerrstr[] = synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47, synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55, synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63, - synerrstr_64, synerrstr_65 + synerrstr_64, synerrstr_65, synerrstr_66 }; #endif /* END: GENERATED WITH generr.moo */ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index af6a925..4e0202f 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2999,6 +2999,9 @@ int moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len) /* TODO: have the pftable sorted alphabetically and do binary search */ for (i = 0; i < MOO_COUNTOF(pftab); i++) { + /* moo_compoocharsbcstr() is not aware of multibyte encoding. + * so the names above should be composed of the single byte + * characters only */ if (moo_compoocharsbcstr(ptr, len, pftab[i].name) == 0) return i; } @@ -3190,11 +3193,18 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) name = method->slot[pf_name_index]; #endif - pfbase = moo_querymod (moo, ((moo_oop_char_t)name)->slot, MOO_OBJ_GET_SIZE(name)); + pfbase = moo_querymod (moo, MOO_OBJ_GET_CHAR_SLOT(name), MOO_OBJ_GET_SIZE(name)); if (pfbase) { int n; + if (nargs < pfbase->minargs || nargs > pfbase->maxargs) + { + MOO_DEBUG5 (moo, "Soft failure due to argument count mismatch for primitive function %.*js - %zu-%zu expected, %zu given\n", + MOO_OBJ_GET_SIZE(name), MOO_OBJ_GET_CHAR_SLOT(name), pfbase->minargs, pfbase->maxargs, nargs); + goto activate_primitive_method_body; + } + /* split a pointer to two OOP fields as SmallIntegers for storing/caching. */ method->preamble_data[0] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase >> (MOO_OOW_BITS / 2)); method->preamble_data[1] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase & MOO_LBMASK(moo_oow_t, MOO_OOW_BITS / 2)); diff --git a/moo/lib/moo-utl.h b/moo/lib/moo-utl.h index 04cb378..7816595 100644 --- a/moo/lib/moo-utl.h +++ b/moo/lib/moo-utl.h @@ -102,6 +102,12 @@ MOO_EXPORT int moo_compucbcstr ( const moo_bch_t* str2 ); +MOO_EXPORT int moo_compucharsucstr ( + const moo_uch_t* str1, + moo_oow_t len, + const moo_uch_t* str2 +); + MOO_EXPORT int moo_compucharsbcstr ( const moo_uch_t* str1, moo_oow_t len, @@ -114,6 +120,12 @@ MOO_EXPORT int moo_compbcharsbcstr ( const moo_bch_t* str2 ); +MOO_EXPORT int moo_compbcharsucstr ( + const moo_bch_t* str1, + moo_oow_t len, + const moo_uch_t* str2 +); + MOO_EXPORT void moo_copyuchars ( moo_uch_t* dst, const moo_uch_t* src, @@ -181,6 +193,8 @@ MOO_EXPORT moo_oow_t moo_countbcstr ( # define moo_equaloochars(str1,str2,len) moo_equaluchars(str1,str2,len) # define moo_compoocbcstr(str1,str2) moo_compucbcstr(str1,str2) # define moo_compoocharsbcstr(str1,len1,str2) moo_compucharsbcstr(str1,len1,str2) +# define moo_compoocharsucstr(str1,len1,str2) moo_compucharsucstr(str1,len1,str2) +# define moo_compoocharsoocstr(str1,len1,str2) moo_compucharsucstr(str1,len1,str2) # define moo_compoocstr(str1,str2) moo_compucstr(str1,str2) # define moo_copyoochars(dst,src,len) moo_copyuchars(dst,src,len) # define moo_copybctooochars(dst,src,len) moo_copybtouchars(dst,src,len) @@ -193,6 +207,8 @@ MOO_EXPORT moo_oow_t moo_countbcstr ( # define moo_equaloochars(str1,str2,len) moo_equalbchars(str1,str2,len) # define moo_compoocbcstr(str1,str2) moo_compbcstr(str1,str2) # define moo_compoocharsbcstr(str1,len1,str2) moo_compbcharsbcstr(str1,len1,str2) +# define moo_compoocharsucstr(str1,len1,str2) moo_compbcharsucstr(str1,len1,str2) +# define moo_compoocharsoocstr(str1,len1,str2) moo_compbcharsbcstr(str1,len1,str2) # define moo_compoocstr(str1,str2) moo_compbcstr(str1,str2) # define moo_copyoochars(dst,src,len) moo_copybchars(dst,src,len) # define moo_copybctooochars(dst,src,len) moo_copybchars(dst,src,len) diff --git a/moo/lib/moo.c b/moo/lib/moo.c index c54fe54..b16037c 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -647,7 +647,7 @@ moo_pfbase_t* moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidle if (!mdp) return MOO_NULL; } - if ((pfbase = mdp->mod.query (moo, &mdp->mod, sep + 1)) == MOO_NULL) + if ((pfbase = mdp->mod.query (moo, &mdp->mod, sep + 1, pfidlen - mod_name_len - 1)) == MOO_NULL) { /* the primitive function is not found. but keep the module open even if it's opened above */ MOO_DEBUG2 (moo, "Cannot find a primitive function [%js] in a module [%js]\n", sep + 1, mdp->mod.name); @@ -655,7 +655,8 @@ moo_pfbase_t* moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidle return MOO_NULL; } - MOO_DEBUG3 (moo, "Found a primitive function [%js] in a module [%js] - %p\n", sep + 1, mdp->mod.name, pfbase); + MOO_DEBUG4 (moo, "Found a primitive function [%.*js] in a module [%js] - %p\n", + pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name, pfbase); return pfbase; } @@ -795,7 +796,7 @@ int moo_genpfmethods (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, const } #endif -moo_pfbase_t* moo_findpfbase (moo_t* moo, const moo_pfinfo_t* pfinfo, moo_oow_t pfcount, const moo_ooch_t* name) +moo_pfbase_t* moo_findpfbase (moo_t* moo, moo_pfinfo_t* pfinfo, moo_oow_t pfcount, const moo_ooch_t* name, moo_oow_t namelen) { int left, right, mid, n; @@ -805,13 +806,10 @@ moo_pfbase_t* moo_findpfbase (moo_t* moo, const moo_pfinfo_t* pfinfo, moo_oow_t { mid = (left + right) / 2; - n = moo_compoocstr (name, pfinfo[mid].mthname); + n = moo_compoocharsoocstr (name, namelen, pfinfo[mid].mthname); if (n < 0) right = mid - 1; else if (n > 0) left = mid + 1; - else - { - return &pfinfo[mid].base; - } + else return &pfinfo[mid].base; } moo->errnum = MOO_ENOENT; diff --git a/moo/lib/moo.h b/moo/lib/moo.h index f481151..08aedf2 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -870,7 +870,8 @@ typedef int (*moo_mod_import_t) ( typedef moo_pfbase_t* (*moo_mod_query_t) ( moo_t* moo, moo_mod_t* mod, - const moo_ooch_t* name + const moo_ooch_t* name, + moo_oow_t namelen ); typedef void (*moo_mod_unload_t) ( @@ -1253,8 +1254,9 @@ enum moo_synerrnum_t MOO_SYNERR_BLKARGFLOOD, /* too many block arguments */ MOO_SYNERR_BLKFLOOD, /* too large block */ MOO_SYNERR_ARREXPFLOOD, /* too large array expression */ - MOO_SYNERR_PFNUMINVAL, /* wrong primitive number */ - MOO_SYNERR_PFIDINVAL, /* wrong primitive identifier */ + MOO_SYNERR_PFNUMINVAL, /* wrong primitive function number */ + MOO_SYNERR_PFIDINVAL, /* wrong primitive function identifier */ + MOO_SYNERR_PFARGDEFINVAL, /* wrong primitive function argument definition */ MOO_SYNERR_MODNAMEINVAL, /* wrong module name */ MOO_SYNERR_INCLUDE, /* #include error */ MOO_SYNERR_NAMESPACEINVAL, /* wrong namespace name */ @@ -1579,9 +1581,10 @@ MOO_EXPORT int moo_genpfmethods ( MOO_EXPORT moo_pfbase_t* moo_findpfbase ( moo_t* moo, - const moo_pfinfo_t* pfinfo, + moo_pfinfo_t* pfinfo, moo_oow_t pfcount, - const moo_ooch_t* name + const moo_ooch_t* name, + moo_oow_t namelen ); /* ========================================================================= diff --git a/moo/lib/utl.c b/moo/lib/utl.c index 35226aa..4b5e6e5 100644 --- a/moo/lib/utl.c +++ b/moo/lib/utl.c @@ -107,6 +107,15 @@ int moo_compucbcstr (const moo_uch_t* str1, const moo_bch_t* str2) return (*str1 > *str2)? 1: -1; } +int moo_compucharsucstr (const moo_uch_t* str1, moo_oow_t len, const moo_uch_t* str2) +{ + const moo_uch_t* end = str1 + len; + while (str1 < end && *str2 != '\0' && *str1 == *str2) str1++, str2++; + if (str1 == end && *str2 == '\0') return 0; + if (*str1 == *str2) return (str1 < end)? 1: -1; + return (*str1 > *str2)? 1: -1; +} + int moo_compucharsbcstr (const moo_uch_t* str1, moo_oow_t len, const moo_bch_t* str2) { const moo_uch_t* end = str1 + len; @@ -125,6 +134,16 @@ int moo_compbcharsbcstr (const moo_bch_t* str1, moo_oow_t len, const moo_bch_t* return (*str1 > *str2)? 1: -1; } +int moo_compbcharsucstr (const moo_bch_t* str1, moo_oow_t len, const moo_uch_t* str2) +{ + const moo_bch_t* end = str1 + len; + while (str1 < end && *str2 != '\0' && *str1 == *str2) str1++, str2++; + if (str1 == end && *str2 == '\0') return 0; + if (*str1 == *str2) return (str1 < end)? 1: -1; + return (*str1 > *str2)? 1: -1; +} + + void moo_copyuchars (moo_uch_t* dst, const moo_uch_t* src, moo_oow_t len) { /* take note of no forced null termination */ diff --git a/moo/mod/console.c b/moo/mod/console.c index ac06c87..c28f35c 100644 --- a/moo/mod/console.c +++ b/moo/mod/console.c @@ -263,9 +263,9 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) return 0; } -static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) { - return moo_findpfbase(moo, pfinfos, MOO_COUNTOF(pfinfos), name); + return moo_findpfbase(moo, pfinfos, MOO_COUNTOF(pfinfos), name, namelen); } diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index 55dc382..f1d6d3f 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -545,9 +545,9 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) return 0; } -static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) { - return moo_findpfbase (moo, pfinfos, MOO_COUNTOF(pfinfos), name); + return moo_findpfbase (moo, pfinfos, MOO_COUNTOF(pfinfos), name, namelen); } static void unload (moo_t* moo, moo_mod_t* mod) diff --git a/moo/mod/stdio.c b/moo/mod/stdio.c index 43a359e..f0b13ae 100644 --- a/moo/mod/stdio.c +++ b/moo/mod/stdio.c @@ -227,9 +227,9 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) /*return moo_genpfmethods (moo, mod, _class, pfinfos, MOO_COUNTOF(pfinfos));*/ } -static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +static moo_pfbase_t* query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) { - return moo_findpfbase (moo, pfinfos, MOO_COUNTOF(pfinfos), name); + return moo_findpfbase (moo, pfinfos, MOO_COUNTOF(pfinfos), name, namelen); } #if 0 diff --git a/moo/mod/x11.c b/moo/mod/x11.c index 8754962..e3dc34e 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -499,9 +499,9 @@ static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) return 0; } -static moo_pfbase_t* x11_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +static moo_pfbase_t* x11_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) { - return moo_findpfbase (moo, x11_pfinfo, MOO_COUNTOF(x11_pfinfo), name); + return moo_findpfbase (moo, x11_pfinfo, MOO_COUNTOF(x11_pfinfo), name, namelen); } static void x11_unload (moo_t* moo, moo_mod_t* mod) @@ -573,9 +573,9 @@ static int x11_gc_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) return 0; } -static moo_pfbase_t* x11_gc_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +static moo_pfbase_t* x11_gc_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) { - return moo_findpfbase(moo, x11_gc_pfinfo, MOO_COUNTOF(x11_gc_pfinfo), name); + return moo_findpfbase(moo, x11_gc_pfinfo, MOO_COUNTOF(x11_gc_pfinfo), name, namelen); } static void x11_gc_unload (moo_t* moo, moo_mod_t* mod) @@ -614,9 +614,9 @@ static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) return 0; } -static moo_pfbase_t* x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) +static moo_pfbase_t* x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name, moo_oow_t namelen) { - return moo_findpfbase(moo, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo), name); + return moo_findpfbase(moo, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo), name, namelen); } static void x11_win_unload (moo_t* moo, moo_mod_t* mod)