changed hawk_rtx_valtomodfnc() to hawk_rtx_valtofnc()
This commit is contained in:
parent
324274bc16
commit
f4354fffa0
@ -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;
|
||||
}
|
||||
|
@ -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_;
|
||||
@ -3381,10 +3382,19 @@ HAWK_EXPORT hawk_fun_t* hawk_rtx_valtofun (
|
||||
hawk_val_t* val
|
||||
);
|
||||
|
||||
HAWK_EXPORT hawk_mod_t* hawk_rtx_valtomodfnc (
|
||||
/**
|
||||
* 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_spec_t* spec
|
||||
hawk_fnc_t* fnc /**< buffer to hold the function information */
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -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()) */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* ========================================================================== */
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user