From ef9db73f1983b9306190e29f640fbca1964328fe Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 14 Apr 2020 11:45:52 +0000 Subject: [PATCH] fixed a bug in handling a reference value in hawk::call() --- hawk/lib/mod-hawk.c | 18 +++++++++++++++--- hawk/lib/run.c | 16 ++-------------- hawk/t/h-001.hawk | 11 ++++++++--- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/hawk/lib/mod-hawk.c b/hawk/lib/mod-hawk.c index 6a2fa3b0..312f0227 100644 --- a/hawk/lib/mod-hawk.c +++ b/hawk/lib/mod-hawk.c @@ -56,14 +56,26 @@ static hawk_oow_t push_args_from_stack (hawk_rtx_t* rtx, hawk_nde_fncall_t* call org_stack_base = rtx->stack_base; for (i = pasf->start_index, j = 0; i <= pasf->end_index; i++, j++) { + hawk_ooch_t spec; + rtx->stack_base = pasf->stack_base; v = HAWK_RTX_STACK_ARG(rtx, i); rtx->stack_base = org_stack_base; - if (j < spec_len && pasf->fun->argspec[j] == 'r' && HAWK_RTX_GETVALTYPE(rtx, v) != HAWK_VAL_REF) + /* if not sufficient number of spec characters given, take the last value and use it */ + spec = (spec_len <= 0)? '\0': pasf->fun->argspec[((j < spec_len)? j: spec_len - 1)]; + + if (HAWK_RTX_GETVALTYPE(rtx, v) == HAWK_VAL_REF) { - hawk_rtx_seterrnum (rtx, &call->loc, HAWK_ENOTREF); - return (hawk_oow_t)-1; + v = hawk_rtx_getrefval(rtx, (hawk_val_ref_t*)v); + } + else + { + if (spec == 'r') + { + hawk_rtx_seterrnum (rtx, &call->loc, HAWK_ENOTREF); + return (hawk_oow_t)-1; + } } HAWK_RTX_STACK_PUSH (rtx, v); diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 05044d6a..2a4413e8 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -6377,20 +6377,8 @@ static hawk_oow_t push_arg_from_nde (hawk_rtx_t* rtx, hawk_nde_fncall_t* call, v { hawk_ooch_t spec; - if (spec_len > 0) - { - if (nargs >= spec_len) - { - /* not sufficient number of spec characters given. - * take the last value and use it */ - spec = arg_spec[spec_len - 1]; - } - else - { - spec = arg_spec[nargs]; - } - } - else spec = '\0'; + /* if not sufficient number of spec characters given, take the last value and use it */ + spec = (spec_len <= 0)? '\0': arg_spec[((nargs < spec_len)? nargs: spec_len - 1)]; switch (spec) { diff --git a/hawk/t/h-001.hawk b/hawk/t/h-001.hawk index 1c90a491..7aeabb16 100644 --- a/hawk/t/h-001.hawk +++ b/hawk/t/h-001.hawk @@ -1,10 +1,11 @@ @pragma entry main + function ensure (a, b, desc) { if (a != b) { - print "FAILURE", desc; + print "FAILURE in", desc; exit (-1); } } @@ -18,6 +19,7 @@ function call_by_ref_1(&a, b, &c) function call_by_ref_2(a, &b) { b[1] = b[1] * a; + b[2] = "perfect"; return a; } @@ -27,12 +29,13 @@ function main() x = 20; y = 90; r = call_by_ref_1(x, y, z); - ensure (r, 1800); + ensure (r, 1800, SCRIPTNAME); ensure (x, 20); ensure (y, 90); ensure (z, "hello, world"); ## TODO: add a new special word, @FILENAME, @FILELINE, @LINE <--- which are understood by the parser and swapped to the actual value +## SCRIPTNAME doesn't tell the main file. { @local b; @@ -53,7 +56,9 @@ function main() b[1] = 1; r = hawk::call("call_by_ref_2", 99, b); ensure (r, 99); - ensure (b[1], 99); + ensure (length(b), 2, SCRIPTNAME); + ensure (b[1], 99, SCRIPTNAME); + ensure (b[2], "perfect", SCRIPTNAME); } print "SUCCESS"