From f08ba4cd12629c55df617fa11a438b299ec9adab Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 16 May 2024 19:40:43 +0900 Subject: [PATCH] fixed to clear inner data upon an error in the interactive mode --- bin/hcl.c | 14 +++++++++----- lib/comp.c | 9 +++++++-- lib/exec.c | 2 +- lib/hcl.h | 4 ++++ lib/read.c | 21 ++++++++++++++------- lib/std.c | 2 +- 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/bin/hcl.c b/bin/hcl.c index 67f1241..65f743b 100644 --- a/bin/hcl.c +++ b/bin/hcl.c @@ -533,14 +533,13 @@ static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj) if (hcl_compile(hcl, obj, flags) <= -1) { - print_error(hcl, "failed to compile"); + /*print_error(hcl, "failed to compile"); */ xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */ - } - else - { - xtn->feed.ncompexprs++; + return -1; /* this causes the feed function to fail and + the error hander for to print the error message */ } + xtn->feed.ncompexprs++; return 0; } @@ -641,6 +640,11 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) { print_error (hcl, "failed to feed"); if (len > 0) show_prompt (hcl, 0); + + /* clear the compiled code but not executed yet */ + hcl_clearcode(hcl); + hcl_clearfnblks(hcl); + xtn->feed.ncompexprs = 0; } else { diff --git a/lib/comp.c b/lib/comp.c index 86af99d..cb5ed3b 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -1242,6 +1242,12 @@ static void pop_fnblk (hcl_t* hcl) } } +void hcl_clearfnblks (hcl_t* hcl) +{ + while (hcl->c->fnblk.depth >= 0) pop_fnblk (hcl); + HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1); +} + /* ========================================================================= */ static HCL_INLINE int _insert_cframe (hcl_t* hcl, hcl_ooi_t index, int opcode, hcl_cnode_t* operand) { @@ -5891,8 +5897,7 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags) * in the interactive mode, the information doesn't have * to get carried over. */ - while (hcl->c->fnblk.depth >= 0) pop_fnblk (hcl); - HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1); + hcl_clearfnblks (hcl); /* it will be recreated below */ } if (flags & HCL_COMPILE_CLEAR_CODE) hcl_clearcode (hcl); diff --git a/lib/exec.c b/lib/exec.c index 94a20c3..5c2b23c 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -372,7 +372,7 @@ static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode) static HCL_INLINE hcl_oop_context_t make_context (hcl_t* hcl, hcl_ooi_t ntmprs) { HCL_ASSERT (hcl, ntmprs >= 0); - //return (hcl_oop_context_t)hcl_allocoopobj(hcl, HCL_BRAND_CONTEXT, HCL_CONTEXT_NAMED_INSTVARS + (hcl_oow_t)ntmprs); + /*return (hcl_oop_context_t)hcl_allocoopobj(hcl, HCL_BRAND_CONTEXT, HCL_CONTEXT_NAMED_INSTVARS + (hcl_oow_t)ntmprs);*/ return (hcl_oop_context_t)hcl_instantiatewithtrailer(hcl, hcl->c_block_context, ntmprs, HCL_NULL, 0); } diff --git a/lib/hcl.h b/lib/hcl.h index 4e8aa2e..a5d1e39 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -2568,6 +2568,10 @@ HCL_EXPORT void hcl_clearcode ( hcl_t* hcl ); +HCL_EXPORT void hcl_clearfnblks ( + hcl_t* hcl +); + #if defined(HCL_HAVE_INLINE) static HCL_INLINE hcl_code_t* hcl_getcode (hcl_t* hcl) { return &hcl->code; } static HCL_INLINE hcl_oob_t* hcl_getbcptr (hcl_t* hcl) { return hcl->code.bc.ptr; } diff --git a/lib/read.c b/lib/read.c index a8e1bfb..9869862 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1144,7 +1144,10 @@ static int feed_begin_include (hcl_t* hcl) return 0; oops: - if (arg) hcl_freemem (hcl, arg); + if (arg) + { + hcl_freemem (hcl, arg); + } return -1; } @@ -3100,7 +3103,7 @@ static int feed_from_includee (hcl_t* hcl) { const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl); hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "unable to read bytes from %js - %js", curinp->name, orgmsg); - return -1; + goto oops; } if (curinp->xlen <= 0) @@ -3109,7 +3112,7 @@ static int feed_from_includee (hcl_t* hcl) if (curinp->rsd.len > 0) { hcl_seterrbfmt (hcl, HCL_EECERR, "incomplete byte sequence in %js", curinp->name); - return -1; + goto oops; } feed_end_include (hcl); curinp = hcl->c->curinp; @@ -3139,7 +3142,7 @@ static int feed_from_includee (hcl_t* hcl) { /* TODO: more accurate location of the invalid byte sequence */ hcl_seterrbfmt (hcl, HCL_EECERR, "invalid byte sequence in %js", curinp->name); - return -1; + goto oops; } if (n > inplen) /* incomplete sequence */ { @@ -3172,7 +3175,7 @@ static int feed_from_includee (hcl_t* hcl) /* TODO: more accurate location of failure */ const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl); hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "unable to read %js - %js", curinp->name, orgmsg); - return -1; + goto oops; } if (curinp->xlen <= 0) { @@ -3193,7 +3196,7 @@ static int feed_from_includee (hcl_t* hcl) #endif x = feed_char(hcl, c); - if (x <= -1) return -1; + if (x <= -1) goto oops; if (x >= 1) { /* consumed */ @@ -3211,13 +3214,17 @@ static int feed_from_includee (hcl_t* hcl) * to include the file. the file inclusion is attempted here after the return * value of feed_char() is used to advance the hcl->c->curinp->b.pos pointer. */ hcl->c->feed.rd.do_include_file = 0; /* clear this regardless of inclusion result */ - if (feed_begin_include(hcl) <= -1) return -1; + if (feed_begin_include(hcl) <= -1) goto oops; curinp = hcl->c->curinp; } } while (curinp != &hcl->c->cci_arg); return 0; + +oops: + while (feed_end_include(hcl) >= 1) /* loop */; /* roll back the entire inclusion chain */ + return -1; } int hcl_beginfeed (hcl_t* hcl, hcl_on_cnode_t on_cnode) diff --git a/lib/std.c b/lib/std.c index 967d292..9a956fb 100644 --- a/lib/std.c +++ b/lib/std.c @@ -3442,7 +3442,7 @@ static HCL_INLINE int read_cci_stream (hcl_t* hcl, hcl_io_cciarg_t* arg) { if (ferror((FILE*)bb->fp)) { - hcl_seterrnum (hcl, HCL_EIOERR); + hcl_seterrbfmt (hcl, HCL_EIOERR, "I/O error - %hs", strerror(errno)); return -1; } break;