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:
parent
f827a94d64
commit
11fe4e17ad
@ -3507,44 +3507,8 @@ static hawk_val_t* eval_expression0 (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v && HAWK_RTX_GETVALTYPE(rtx, v) == HAWK_VAL_REF)
|
/* this function returns a regular expression without further mathiching.
|
||||||
{
|
* it is done in eval_expression(). */
|
||||||
/* 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
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);
|
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_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
|
||||||
hawk_fun_t* fun;
|
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_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, fun->argspec, errhandler, eharg);
|
/* 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
|
||||||
static hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
* but its evaluation result is passed to user-defined function.
|
||||||
{
|
* I pass HAWK_NULL to prevent special handling.
|
||||||
return eval_fncall_fun_ex(rtx, nde, HAWK_NULL, HAWK_NULL);
|
* 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)
|
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)
|
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);
|
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);
|
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
|
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);
|
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;
|
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;
|
spec_len = arg_spec? hawk_count_oocstr(arg_spec): 0;
|
||||||
for (p = call->args, nargs = 0; p; p = p->next, nargs++)
|
for (p = call->args, nargs = 0; p; p = p->next, nargs++)
|
||||||
{
|
{
|
||||||
|
@ -177,14 +177,6 @@ function handle_bridge_event (&brtab, fd, mx, evmask)
|
|||||||
{
|
{
|
||||||
if (evmask & sys::MUX_EVT_OUT)
|
if (evmask & sys::MUX_EVT_OUT)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
@local i;
|
|
||||||
print typename(brtab);
|
|
||||||
for (i in brtab)
|
|
||||||
{
|
|
||||||
print i, brtab[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((fd,"connecting") in brtab)
|
if ((fd,"connecting") in brtab)
|
||||||
{
|
{
|
||||||
## remote peer connection
|
## remote peer connection
|
||||||
|
Loading…
x
Reference in New Issue
Block a user