fixed a bug where a reference value was passed to a user-defined function. a reference value should have been evaluated to a non-reference value before given to a user-defined function. it's a new bug introduced over a few previous commits done to support hawk::call()

This commit is contained in:
hyung-hwan 2020-04-14 06:47:46 +00:00
parent f827a94d64
commit 11fe4e17ad
2 changed files with 25 additions and 55 deletions

View File

@ -3507,44 +3507,8 @@ static hawk_val_t* eval_expression0 (hawk_rtx_t* rtx, hawk_nde_t* nde)
return HAWK_NULL;
}
if (v && HAWK_RTX_GETVALTYPE(rtx, v) == HAWK_VAL_REF)
{
/* as a rvalue, a reference can get resolved to a final value */
hawk_val_ref_t* ref = (hawk_val_ref_t*)v;
hawk_val_t* nv;
printf ("REF>>>>>>>>>>>>>>>>>>>>> %d\n", ref->id);
switch (ref->id)
{
case HAWK_VAL_REF_POS:
{
hawk_oow_t idx = (hawk_oow_t)ref->adr;
nv = POS_VAL(rtx, idx);
break;
}
case HAWK_VAL_REF_NAMED:
case HAWK_VAL_REF_NAMEDIDX:
{
hawk_oow_t idx = (hawk_oow_t)ref->adr;
printf ("XXXXXXXXXXXXXXX[%lu]\n", (unsigned long)idx);
nv = HAWK_RTX_STACK_GBL(rtx, idx);
break;
}
default:
nv = *(hawk_val_t**)ref->adr;
break;
}
hawk_rtx_refupval (rtx, v);
hawk_rtx_refdownval (rtx, v);
v = nv;
printf ("---- %d\n", HAWK_RTX_GETVALTYPE(rtx, v));
}
/* this function returns a regular expression without further mathiching.
* it is done in eval_expression(). */
return v;
}
@ -5930,7 +5894,7 @@ static hawk_val_t* eval_fncall_fnc (hawk_rtx_t* rtx, hawk_nde_t* nde)
return hawk_rtx_evalcall(rtx, call, HAWK_NULL, push_arg_from_nde, (void*)call->u.fnc.spec.arg.spec, HAWK_NULL, HAWK_NULL);
}
static HAWK_INLINE hawk_val_t* eval_fncall_fun_ex (hawk_rtx_t* rtx, hawk_nde_t* nde, void(*errhandler)(void*), void* eharg)
static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde)
{
hawk_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
hawk_fun_t* fun;
@ -5971,12 +5935,15 @@ static HAWK_INLINE hawk_val_t* eval_fncall_fun_ex (hawk_rtx_t* rtx, hawk_nde_t*
return HAWK_NULL;
}
return hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, fun->argspec, errhandler, eharg);
}
static hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde)
{
return eval_fncall_fun_ex(rtx, nde, HAWK_NULL, HAWK_NULL);
/* push_arg_from_nde() has special handling for references when the function
* argument spec contains 'r' or 'R'.
* a reference is passed to a built-in function as a reference value
* but its evaluation result is passed to user-defined function.
* I pass HAWK_NULL to prevent special handling.
* the value change for a reference variable inside a user-defined function is reflected by hawk_rtx_evalcall()
* specially whereas a built-in function must call hawk_rtx_setrefval() to update the reference
*/
return hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, HAWK_NULL/*fun->argspec*/, HAWK_NULL, HAWK_NULL);
}
static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
@ -5994,12 +5961,21 @@ static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
{
if (hawk_rtx_geterrnum(rtx) == HAWK_EINVAL)
hawk_rtx_seterrfmt (rtx, &nde->loc, HAWK_ENOTFUN, HAWK_T("non-function value in %.*js"), call->u.var.var->id.name.len, call->u.var.var->id.name.ptr);
rv = HAWK_NULL;
ADJERR_LOC (rtx, &nde->loc);
rv = HAWK_NULL;
}
else if (call->nargs > fun->nargs)
{
/* TODO: is this correct? what if i want to
* allow arbitarary numbers of arguments? */
hawk_rtx_seterrnum (rtx, &nde->loc, HAWK_EARGTM);
rv = HAWK_NULL;
}
else
{
rv = hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, fun->argspec, HAWK_NULL, HAWK_NULL);
/* pass HAWK_NULL for the argument spec regardless of the actual spec.
* see comments in eval_fncall_fun() for more */
rv = hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, HAWK_NULL/*fun->argspec*/, HAWK_NULL, HAWK_NULL);
}
hawk_rtx_refdownval (rtx, fv);
@ -6394,6 +6370,8 @@ static hawk_oow_t push_arg_from_nde (hawk_rtx_t* rtx, hawk_nde_fncall_t* call, v
return (hawk_oow_t)-1;
}
/* in practice, this function gets NULL for a user-defined function regardless of its actual spec.
* it may get a non-NULL arg_spec for builtin/module functions */
spec_len = arg_spec? hawk_count_oocstr(arg_spec): 0;
for (p = call->args, nargs = 0; p; p = p->next, nargs++)
{

View File

@ -177,14 +177,6 @@ function handle_bridge_event (&brtab, fd, mx, evmask)
{
if (evmask & sys::MUX_EVT_OUT)
{
{
@local i;
print typename(brtab);
for (i in brtab)
{
print i, brtab[i];
}
}
if ((fd,"connecting") in brtab)
{
## remote peer connection