implemented more prechecks including the existence of the primitive function handler and the number of supported arguments when compiling primitive method defintions

This commit is contained in:
hyunghwan.chung 2017-03-31 14:21:22 +00:00
parent 0f84a115ae
commit 447670aba8
14 changed files with 172 additions and 80 deletions

View File

@ -1,7 +1,7 @@
class _FFI(Object) from 'ffi' class _FFI(Object) from 'ffi'
{ {
method(#primitive) open(name). method(#primitive) open(name).
method(#primitive) close(). method(#primitive) close.
method(#primitive) getsym(name). method(#primitive) getsym(name).
(* TODO: make call variadic? method(#primitive,#variadic) call (func, sig). *) (* TODO: make call variadic? method(#primitive,#variadic) call (func, sig). *)

View File

@ -115,7 +115,6 @@ class MyObject(Object)
{ {
|a k| |a k|
'BEGINNING OF main...........' dump. 'BEGINNING OF main...........' dump.
a := a :=
if ([System logNl: 'xxxx'. 'abcd' == 'bcde'. false] value) if ([System logNl: 'xxxx'. 'abcd' == 'bcde'. false] value)
@ -270,6 +269,8 @@ class MyObject(Object)
{ {
|a i| |a i|
###self main_xx.
a := 100. a := 100.
## PROBLEM: the following double loop will exhaust the stack ## PROBLEM: the following double loop will exhaust the stack
(* (*

View File

@ -99,6 +99,7 @@ class MyObject(Object)
'too large array expression' 'too large array expression'
'wrong primitive function number' 'wrong primitive function number'
'wrong primitive function identifier' 'wrong primitive function identifier'
'wrong primitive function argument definition'
'wrong module name' 'wrong module name'
'#include error' '#include error'
'wrong namespace name' 'wrong namespace name'
@ -130,18 +131,15 @@ class MyObject(Object)
]. ].
f puts: S'static moo_ooch_t* '. f puts(S'static moo_ooch_t* ', name, S'[] =\n{\n').
f puts: name.
f puts: S'[] =\n{\n'.
0 to: c do: [:i | 0 to: c do: [:i |
((i rem: 8) = 0) ifTrue: [ f putc: C'\t' ]. ((i rem: 8) = 0) ifTrue: [ f putc(C'\t') ].
f puts: prefix. f puts(prefix, (i asString)).
f puts: (i asString). (i = c) ifFalse: [f puts(S',') ].
(i = c) ifFalse: [f puts: S',' ]. (((i + 1) rem: 8) = 0) ifTrue: [ f putc(C'\n') ] ifFalse: [ f putc(C' ') ].
(((i + 1) rem: 8) = 0) ifTrue: [ f putc: C'\n' ] ifFalse: [ f putc: C' ' ].
]. ].
(((c + 1) rem: 8) = 0) ifFalse: [ f putc: C'\n' ]. (((c + 1) rem: 8) = 0) ifFalse: [ f putc(C'\n') ].
f puts: S'};\n'. f puts(S'};\n').
} }
method(#class) printString: s prefix: prefix index: index on: f method(#class) printString: s prefix: prefix index: index on: f
@ -149,18 +147,13 @@ class MyObject(Object)
| c | | c |
c := s size - 1. c := s size - 1.
f puts: 'static moo_ooch_t '. f puts('static moo_ooch_t ', prefix, index asString, '[] = {').
f puts: prefix.
f puts: index asString.
f puts: '[] = {'.
0 to: c do: [:i | 0 to: c do: [:i |
f putc: $'. f putc($', (s at: i), $').
f putc: (s at: i). (i = c) ifFalse: [f putc($,) ].
f putc: $'.
(i = c) ifFalse: [f putc: $, ].
]. ].
f puts: S',\'\\0\'};\n'. f puts(S',\'\\0\'};\n').
} }
} }

View File

@ -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; 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; pos = dst->len;
len = dst->len + src->len; len = dst->len + src->len;
if (add_delim != '\0') len++; if (delim_char != '\0') len++;
} }
else 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; *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); moo_copyoochars (&dst->ptr[pos], src->ptr, src->len);
dst->len = len; dst->len = len;
return 0; 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); 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; moo_oop_t tmp;
@ -3391,6 +3391,8 @@ static int compile_method_primitive (moo_t* moo)
ptr++; ptr++;
} }
/* TODO: check if the number points to one of the internal primitive function */
moo->c->mth.pfnum = pfnum; moo->c->mth.pfnum = pfnum;
break; break;
@ -3409,29 +3411,55 @@ static int compile_method_primitive (moo_t* moo)
/* a built-in primitive function is not found /* a built-in primitive function is not found
* check if it is a primitive function identifier */ * check if it is a primitive function identifier */
moo_oow_t lit_idx; moo_oow_t lit_idx;
moo_pfbase_t* pfbase;
if (moo_findoochar (tptr, tlen, '.') && if (!moo_rfindoochar (tptr, tlen, '.'))
add_symbol_literal(moo, TOKEN_NAME(moo), 1, &lit_idx) >= 0 &&
MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx))
{ {
/* external named primitive containing a period. */ /* wrong primitive functio identifier */
moo->c->mth.pftype = PFTYPE_NAMED; set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
moo->c->mth.pfnum = lit_idx; return -1;
break;
} }
/* wrong primitive number */ /* external named primitive containing a period. */
set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; /* 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)) else if (!MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(pfnum))
{ {
set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; 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; break;
} }
@ -5877,6 +5905,9 @@ static int compile_method_definition (moo_t* moo)
if (moo->c->cls.self_oop->modname == moo->_nil) 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_oow_t savedlen;
moo_ooi_t pfnum; 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); 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)) 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, &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); set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
moo->c->cls.modname.len = savedlen;
return -1; return -1;
} }
/* TODO: check argumetns... */
moo->c->cls.modname.len = savedlen; moo->c->cls.modname.len = savedlen;
moo->c->mth.pftype = PFTYPE_NUMBERED; moo->c->mth.pftype = PFTYPE_NUMBERED;
@ -5911,6 +5943,7 @@ static int compile_method_definition (moo_t* moo)
{ {
moo_oow_t litidx, savedlen; moo_oow_t litidx, savedlen;
moo_oocs_t tmp; moo_oocs_t tmp;
moo_pfbase_t* pfbase;
/* combine the module name and the method name delimited by a period /* 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 * 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.ptr = MOO_OBJ_GET_CHAR_SLOT(moo->c->cls.self_oop->modname);
tmp.len = MOO_OBJ_GET_SIZE(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 || 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 || 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) 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; return -1;
} }
moo->c->cls.modname.len = savedlen; /* 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. /* the symbol added must be the first literal to the current method.
* so this condition must be true. */ * so this condition must be true. */
MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(litidx)); MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(litidx));

View File

@ -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_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_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_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_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[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\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[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','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',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\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[] = {'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_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[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\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[] = {'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_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',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\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[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\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[] = static moo_ooch_t* synerrstr[] =
{ {
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, 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_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_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_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 #endif
/* END: GENERATED WITH generr.moo */ /* END: GENERATED WITH generr.moo */

View File

@ -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 */ /* TODO: have the pftable sorted alphabetically and do binary search */
for (i = 0; i < MOO_COUNTOF(pftab); i++) 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; 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]; name = method->slot[pf_name_index];
#endif #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) if (pfbase)
{ {
int n; 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. */ /* 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[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)); method->preamble_data[1] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase & MOO_LBMASK(moo_oow_t, MOO_OOW_BITS / 2));

View File

@ -102,6 +102,12 @@ MOO_EXPORT int moo_compucbcstr (
const moo_bch_t* str2 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 ( MOO_EXPORT int moo_compucharsbcstr (
const moo_uch_t* str1, const moo_uch_t* str1,
moo_oow_t len, moo_oow_t len,
@ -114,6 +120,12 @@ MOO_EXPORT int moo_compbcharsbcstr (
const moo_bch_t* str2 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_EXPORT void moo_copyuchars (
moo_uch_t* dst, moo_uch_t* dst,
const moo_uch_t* src, 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_equaloochars(str1,str2,len) moo_equaluchars(str1,str2,len)
# define moo_compoocbcstr(str1,str2) moo_compucbcstr(str1,str2) # define moo_compoocbcstr(str1,str2) moo_compucbcstr(str1,str2)
# define moo_compoocharsbcstr(str1,len1,str2) moo_compucharsbcstr(str1,len1,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_compoocstr(str1,str2) moo_compucstr(str1,str2)
# define moo_copyoochars(dst,src,len) moo_copyuchars(dst,src,len) # define moo_copyoochars(dst,src,len) moo_copyuchars(dst,src,len)
# define moo_copybctooochars(dst,src,len) moo_copybtouchars(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_equaloochars(str1,str2,len) moo_equalbchars(str1,str2,len)
# define moo_compoocbcstr(str1,str2) moo_compbcstr(str1,str2) # define moo_compoocbcstr(str1,str2) moo_compbcstr(str1,str2)
# define moo_compoocharsbcstr(str1,len1,str2) moo_compbcharsbcstr(str1,len1,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_compoocstr(str1,str2) moo_compbcstr(str1,str2)
# define moo_copyoochars(dst,src,len) moo_copybchars(dst,src,len) # define moo_copyoochars(dst,src,len) moo_copybchars(dst,src,len)
# define moo_copybctooochars(dst,src,len) moo_copybchars(dst,src,len) # define moo_copybctooochars(dst,src,len) moo_copybchars(dst,src,len)

View File

@ -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 (!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 */ /* 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); 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; 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; return pfbase;
} }
@ -795,7 +796,7 @@ int moo_genpfmethods (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, const
} }
#endif #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; 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; 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; if (n < 0) right = mid - 1;
else if (n > 0) left = mid + 1; else if (n > 0) left = mid + 1;
else else return &pfinfo[mid].base;
{
return &pfinfo[mid].base;
}
} }
moo->errnum = MOO_ENOENT; moo->errnum = MOO_ENOENT;

View File

@ -870,7 +870,8 @@ typedef int (*moo_mod_import_t) (
typedef moo_pfbase_t* (*moo_mod_query_t) ( typedef moo_pfbase_t* (*moo_mod_query_t) (
moo_t* moo, moo_t* moo,
moo_mod_t* mod, moo_mod_t* mod,
const moo_ooch_t* name const moo_ooch_t* name,
moo_oow_t namelen
); );
typedef void (*moo_mod_unload_t) ( typedef void (*moo_mod_unload_t) (
@ -1253,8 +1254,9 @@ enum moo_synerrnum_t
MOO_SYNERR_BLKARGFLOOD, /* too many block arguments */ MOO_SYNERR_BLKARGFLOOD, /* too many block arguments */
MOO_SYNERR_BLKFLOOD, /* too large block */ MOO_SYNERR_BLKFLOOD, /* too large block */
MOO_SYNERR_ARREXPFLOOD, /* too large array expression */ MOO_SYNERR_ARREXPFLOOD, /* too large array expression */
MOO_SYNERR_PFNUMINVAL, /* wrong primitive number */ MOO_SYNERR_PFNUMINVAL, /* wrong primitive function number */
MOO_SYNERR_PFIDINVAL, /* wrong primitive identifier */ MOO_SYNERR_PFIDINVAL, /* wrong primitive function identifier */
MOO_SYNERR_PFARGDEFINVAL, /* wrong primitive function argument definition */
MOO_SYNERR_MODNAMEINVAL, /* wrong module name */ MOO_SYNERR_MODNAMEINVAL, /* wrong module name */
MOO_SYNERR_INCLUDE, /* #include error */ MOO_SYNERR_INCLUDE, /* #include error */
MOO_SYNERR_NAMESPACEINVAL, /* wrong namespace name */ MOO_SYNERR_NAMESPACEINVAL, /* wrong namespace name */
@ -1579,9 +1581,10 @@ MOO_EXPORT int moo_genpfmethods (
MOO_EXPORT moo_pfbase_t* moo_findpfbase ( MOO_EXPORT moo_pfbase_t* moo_findpfbase (
moo_t* moo, moo_t* moo,
const moo_pfinfo_t* pfinfo, moo_pfinfo_t* pfinfo,
moo_oow_t pfcount, moo_oow_t pfcount,
const moo_ooch_t* name const moo_ooch_t* name,
moo_oow_t namelen
); );
/* ========================================================================= /* =========================================================================

View File

@ -107,6 +107,15 @@ int moo_compucbcstr (const moo_uch_t* str1, const moo_bch_t* str2)
return (*str1 > *str2)? 1: -1; 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) int moo_compucharsbcstr (const moo_uch_t* str1, moo_oow_t len, const moo_bch_t* str2)
{ {
const moo_uch_t* end = str1 + len; 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; 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) void moo_copyuchars (moo_uch_t* dst, const moo_uch_t* src, moo_oow_t len)
{ {
/* take note of no forced null termination */ /* take note of no forced null termination */

View File

@ -263,9 +263,9 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
return 0; 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);
} }

View File

@ -545,9 +545,9 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
return 0; 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) static void unload (moo_t* moo, moo_mod_t* mod)

View File

@ -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));*/ /*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 #if 0

View File

@ -499,9 +499,9 @@ static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class)
return 0; 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) 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; 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) 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; 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) static void x11_win_unload (moo_t* moo, moo_mod_t* mod)