changed hawk_rtx_valtomodfnc() to hawk_rtx_valtofnc()

This commit is contained in:
hyung-hwan 2022-04-08 10:52:15 +00:00
parent 324274bc16
commit f4354fffa0
5 changed files with 94 additions and 37 deletions

View File

@ -627,6 +627,7 @@ int hawk_findmodsymfnc_noseterr (hawk_t* hawk, hawk_mod_fnc_tab_t* fnctab, hawk_
if (n == 0)
{
sym->type = HAWK_MOD_FNC;
sym->name = fnctab[mid].name;
sym->u.fnc_ = fnctab[mid].info;
return 0;
}
@ -651,6 +652,7 @@ int hawk_findmodsymint_noseterr (hawk_t* hawk, hawk_mod_int_tab_t* inttab, hawk_
if (n == 0)
{
sym->type = HAWK_MOD_INT;
sym->name = inttab[mid].name;
sym->u.int_ = inttab[mid].info;
return 0;
}
@ -674,6 +676,7 @@ int hawk_findmodsymflt_noseterr (hawk_t* hawk, hawk_mod_flt_tab_t* flttab, hawk_
if (n == 0)
{
sym->type = HAWK_MOD_FLT;
sym->name = flttab[mid].name;
sym->u.flt_ = flttab[mid].info;
return 0;
}

View File

@ -1041,6 +1041,7 @@ struct hawk_mod_sym_flt_t
struct hawk_mod_sym_t
{
hawk_mod_sym_type_t type;
const hawk_ooch_t* name;
union
{
hawk_mod_sym_fnc_t fnc_;
@ -1807,7 +1808,7 @@ HAWK_EXPORT int hawk_findgblwithucstr (
*/
HAWK_EXPORT hawk_fnc_t* hawk_addfncwithbcstr (
hawk_t* hawk,
const hawk_bch_t* name,
const hawk_bch_t* name,
const hawk_fnc_mspec_t* spec
);
@ -1816,7 +1817,7 @@ HAWK_EXPORT hawk_fnc_t* hawk_addfncwithbcstr (
*/
HAWK_EXPORT hawk_fnc_t* hawk_addfncwithucstr (
hawk_t* hawk,
const hawk_uch_t* name,
const hawk_uch_t* name,
const hawk_fnc_wspec_t* spec
);
@ -1825,7 +1826,7 @@ HAWK_EXPORT hawk_fnc_t* hawk_addfncwithucstr (
* \return 0 on success, -1 on failure
*/
HAWK_EXPORT int hawk_delfncwithbcstr (
hawk_t* hawk, /**< hawk */
hawk_t* hawk, /**< hawk */
const hawk_bch_t* name /**< function name */
);
@ -1834,7 +1835,7 @@ HAWK_EXPORT int hawk_delfncwithbcstr (
* \return 0 on success, -1 on failure
*/
HAWK_EXPORT int hawk_delfncwithucstr (
hawk_t* hawk, /**< hawk */
hawk_t* hawk, /**< hawk */
const hawk_uch_t* name /**< function name */
);
@ -3381,10 +3382,19 @@ HAWK_EXPORT hawk_fun_t* hawk_rtx_valtofun (
hawk_val_t* val
);
HAWK_EXPORT hawk_mod_t* hawk_rtx_valtomodfnc (
hawk_rtx_t* rtx,
hawk_val_t* val,
hawk_fnc_spec_t* spec
/**
* The hawk_rtx_valtofnc() function finds an intrinsic function by the name
* pointed to by \a val. Unlike hawk_findfncwithoocstr() and the like,
* it accepts a function name prefixed with a module name and find an intrinsic
* function located in a module. In principle, it combines hawk_findfncwithoocstr()
* and hawk_querymodulewithname().
*
* \return \a fnc on success, #HAWK_NULL on failure
*/
HAWK_EXPORT hawk_fnc_t* hawk_rtx_valtofnc (
hawk_rtx_t* rtx,
hawk_val_t* val,
hawk_fnc_t* fnc /**< buffer to hold the function information */
);
/**

View File

@ -104,7 +104,7 @@ static hawk_oow_t push_args_from_stack (hawk_rtx_t* rtx, hawk_nde_fncall_t* call
static int fnc_call (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_fun_t* fun;
hawk_oow_t nargs;
hawk_oow_t nargs, f_nargs;
hawk_nde_fncall_t call;
struct pafs_t pafs;
hawk_val_t* v;
@ -112,11 +112,12 @@ static int fnc_call (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
/* this function is similar to hawk_rtx_callfun() but it is more simplified */
HAWK_MEMSET (&call, 0, HAWK_SIZEOF(call));
nargs = hawk_rtx_getnargs(rtx);
f_nargs = nargs - 1;
fun = hawk_rtx_valtofun(rtx, hawk_rtx_getarg(rtx, 0));
if (fun)
{
if (nargs - 1 > fun->nargs)
if (f_nargs > fun->nargs)
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EARGTM);
return -1; /* hard failure */
@ -133,30 +134,40 @@ static int fnc_call (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
else
{
/* find the name in the modules */
hawk_mod_t* m;
hawk_fnc_t fnc, * fncp;
mod_data_t* md;
// TODO: find normal fnc too.
md = (mod_data_t*)fi->mod->ctx;
/* hawk_querymodulewithname() may update some shared data under
* the hawk object. use a mutex for shared data safety */
hawk_mtx_lock (&md->mq_mtx, HAWK_NULL);
m = hawk_rtx_valtomodfnc(rtx, hawk_rtx_getarg(rtx, 0), &call.u.fnc.spec);
hawk_mtx_unlock (&md->mq_mtx);
if (!m) return -1; /* hard failure */
/* hawk_querymodulewithname() called by hawk_rtx_valtofnc()
* may update some shared data under the hawk object.
* use a mutex for shared data safety */
/* TODO: this mutex protection is wrong in that if a call to hawk_querymodulewithname()
* is made outside this hawk module, the call is not protected under
* the same mutex. FIX THIS */
hawk_mtx_lock (&md->mq_mtx, HAWK_NULL);
fncp = hawk_rtx_valtofnc(rtx, hawk_rtx_getarg(rtx, 0), &fnc);
hawk_mtx_unlock (&md->mq_mtx);
if (!fncp) return -1; /* hard failure */
if (f_nargs < fnc.spec.arg.min || f_nargs > fnc.spec.arg.max)
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EARGTM);
return -1;
}
call.type = HAWK_NDE_FNCALL_FNC;
// QQQ0
// call.u.fnc.info.name = name;
call.u.fnc.info.mod = m;
call.u.fnc.info.name.ptr = fnc.name.ptr;
call.u.fnc.info.name.len = fnc.name.len;
call.u.fnc.info.mod = fnc.mod;
call.u.fnc.spec = fnc.spec;
pafs.is_fun = 0;
pafs.argspec_ptr = call.u.fnc.spec.arg.spec;
pafs.argspec_len = call.u.fnc.spec.arg.spec? hawk_count_oocstr(call.u.fnc.spec.arg.spec): 0;
}
call.nargs = nargs - 1;
call.nargs = f_nargs;
/* keep HAWK_NULL in call.args so that hawk_rtx_evalcall() knows it's a fake call structure */
call.arg_base = rtx->stack_base + 5; /* 5 = 4(stack frame prologue) + 1(the first argument to hawk::call()) */

View File

@ -2821,11 +2821,15 @@ hawk_fun_t* hawk_rtx_valtofun (hawk_rtx_t* rtx, hawk_val_t* v)
return fun;
}
hawk_mod_t* hawk_rtx_valtomodfnc (hawk_rtx_t* rtx, hawk_val_t* v, hawk_fnc_spec_t* spec)
hawk_fnc_t* hawk_rtx_valtofnc (hawk_rtx_t* rtx, hawk_val_t* v, hawk_fnc_t* rfnc)
{
/* this function looks for intrinsic functions as well as module functions.
* it combines the functionality of the following two functions.
* hawk_findfncwithoocs() - finds an intrisic function
* hawk_querymodulewithname() - finds a function defined in a module
*/
hawk_t* hawk = hawk_rtx_gethawk(rtx);
hawk_mod_t* mod;
hawk_mod_sym_t sym;
hawk_val_type_t vtype;
vtype = HAWK_RTX_GETVALTYPE(rtx, v);
@ -2838,6 +2842,8 @@ hawk_mod_t* hawk_rtx_valtomodfnc (hawk_rtx_t* rtx, hawk_val_t* v, hawk_fnc_spec_
case HAWK_VAL_STR:
{
hawk_oocs_t x;
hawk_fnc_t* fnc;
x.ptr = hawk_rtx_getvaloocstr(rtx, v, &x.len);
if (HAWK_UNLIKELY(!x.ptr)) return HAWK_NULL;
if (hawk_count_oocstr(x.ptr) != x.len)
@ -2845,9 +2851,36 @@ hawk_mod_t* hawk_rtx_valtomodfnc (hawk_rtx_t* rtx, hawk_val_t* v, hawk_fnc_spec_
hawk_rtx_freevaloocstr (rtx, v, x.ptr);
goto error_inval;
}
mod = hawk_querymodulewithname(hawk, &x, &sym);
hawk_rtx_freevaloocstr (rtx, v, x.ptr);
if (!mod) return HAWK_NULL;
fnc = hawk_findfncwithoocs(hawk, &x);
if (fnc)
{
hawk_rtx_freevaloocstr (rtx, v, x.ptr);
*rfnc = *fnc;
}
else
{
hawk_mod_t* mod;
hawk_mod_sym_t sym;
mod = hawk_querymodulewithname(hawk, &x, &sym);
hawk_rtx_freevaloocstr (rtx, v, x.ptr);
if (!mod) return HAWK_NULL;
if (sym.type != HAWK_MOD_FNC || (hawk->opt.trait & sym.u.fnc_.trait) != sym.u.fnc_.trait)
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOENT);
return HAWK_NULL;
}
HAWK_MEMSET (rfnc, 0, HAWK_SIZEOF(*rfnc));
rfnc->name.ptr = sym.name;
rfnc->name.len = hawk_count_oocstr(sym.name);
rfnc->spec = sym.u.fnc_;
/* TODO: FIX THIS - set the owner name */
/*rfnc->owner = name of the module?*/
rfnc->mod = mod;
}
break;
}
@ -2857,14 +2890,7 @@ hawk_mod_t* hawk_rtx_valtomodfnc (hawk_rtx_t* rtx, hawk_val_t* v, hawk_fnc_spec_
return HAWK_NULL;
}
if (sym.type != HAWK_MOD_FNC || (hawk->opt.trait & sym.u.fnc_.trait) != sym.u.fnc_.trait)
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOENT);
return HAWK_NULL;
}
*spec = sym.u.fnc_;
return mod;
return rfnc;
}
/* ========================================================================== */

View File

@ -7,9 +7,16 @@ function run_test_001 ()
{
@local tmp, out;
tap_ensure (hawk::function_exists(111), 0, @SCRIPTNAME, @SCRIPTLINE);
tap_ensure (hawk::function_exists(1.69), 0, @SCRIPTNAME, @SCRIPTLINE);
tap_ensure (hawk::function_exists("111"), 0, @SCRIPTNAME, @SCRIPTLINE);
tap_ensure (hawk::function_exists(@b"111"), 0, @SCRIPTNAME, @SCRIPTLINE);
tap_ensure (hawk::call(@b"length", "hawk"), 4, @SCRIPTNAME, @SCRIPTLINE);
tap_ensure (hawk::call("length", @b"hawk"), 4, @SCRIPTNAME, @SCRIPTLINE);
if (hawk::function_exists("sed::str_to_str"))
{
##tmp = sed::str_to_str("s/a/j/g", "aaabbbaaacccaaaddd", out);
tmp = hawk::call("sed::str_to_str", "s/a/j/g", "aaabbbaaacccaaaddd", out);
tap_ensure (out === "jjjbbbjjjcccjjjddd", 1, @SCRIPTNAME, @SCRIPTLINE);
}