diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-04-16 14:16:33 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-04-16 14:16:33 -0700 |
commit | f029f2815c2d69ef833089f476d32cadc5edd2de (patch) | |
tree | 2fa684767bf49a32eca8c0eb9c5a8690ad620c1d | |
parent | a46ef5d5b56f0ca6f69a36ddf131bc3b9658b758 (diff) | |
download | txr-f029f2815c2d69ef833089f476d32cadc5edd2de.tar.gz txr-f029f2815c2d69ef833089f476d32cadc5edd2de.tar.bz2 txr-f029f2815c2d69ef833089f476d32cadc5edd2de.zip |
cmdline: use handler instead of catch for errors.
Errors encountered when parsing or evaluating a source file
should be handled using a handler rather than a catch, so that
the unwind stack is available to the error reporting function.
This anticipates being able to dump a backtrace.
* txr.c (parse_once_noerr, read_eval_stream_noerr): Adjust
to reduced argument count in ignerr_func_body macro.
* unwind.c (uw_trace_error): New function.
* unwind.h (uw_trace_error): Declared.
(ignerr_func_body): Revised to establish a handler in addition
to the catch. The catch now doesn't do anything other than
provide an intercepting exit point; the error_trace call is
moved into the handler, and so it executes in a context where
unwinding hasn't happened yet.
-rw-r--r-- | txr.c | 5 | ||||
-rw-r--r-- | unwind.c | 7 | ||||
-rw-r--r-- | unwind.h | 17 |
3 files changed, 21 insertions, 8 deletions
@@ -472,15 +472,14 @@ static void no_dbg_support(val arg) static int parse_once_noerr(val stream, val name, parser_t *parser) { val pfx = format(nil, lit("~a:"), name, nao); - ignerr_func_body(int, 0, parse_once(stream, name, parser), - exsym, exargs, std_error, pfx); + ignerr_func_body(int, 0, parse_once(stream, name, parser), std_error, pfx); } static val read_eval_stream_noerr(val self, val stream, val name, val error_stream) { val pfx = format(nil, lit("~a:"), name, nao); ignerr_func_body(val, nil, read_eval_stream(self, stream, error_stream), - exsym, exargs, std_error, pfx); + std_error, pfx); } int txr_main(int argc, char **argv) @@ -422,6 +422,13 @@ val uw_muffle_warning(val exc, struct args *args) uw_throw(continue_s, nil); } +val uw_trace_error(val ctx, val exc, struct args *args) +{ + cons_bind (stream, prefix, ctx); + error_trace(exc, args_get_list(args), stream, prefix); + return nil; +} + void uw_push_cont_copy(uw_frame_t *fr, mem_t *ptr, void (*copy)(mem_t *ptr, int parent)) { @@ -145,6 +145,7 @@ val uw_find_frame(val extype, val frtype); val uw_find_frames(val extype, val frtype); val uw_invoke_catch(val catch_frame, val sym, struct args *); val uw_muffle_warning(val exc, struct args *); +val uw_trace_error(val ctx, val exc, struct args *); val uw_capture_cont(val tag, val fun, val ctx_form); void uw_push_cont_copy(uw_frame_t *, mem_t *ptr, void (*copy)(mem_t *ptr, int parent)); @@ -274,13 +275,19 @@ noreturn val type_mismatch(val, ...); #EXPR \ " failed") -#define ignerr_func_body(type, init, expr, exsym, \ - exargs, stream, prefix) \ +#define ignerr_func_body(type, init, expr, \ + stream, prefix) \ + val (_s_y_m_s) = cons(error_s, nil); \ type (_r_e_t) = (init); \ - uw_catch_begin (cons(error_s, nil), exsym, exargs); \ + uw_frame_t _h_n_d; \ + uw_catch_begin (_s_y_m_s, _e_x, _e_x_a); \ + uw_push_handler(&_h_n_d, _s_y_m_s, \ + func_f1v(cons(stream, prefix), \ + uw_trace_error)); \ _r_e_t = expr; \ - uw_catch(exsym, exargs) \ - error_trace(exsym, exargs, stream, prefix); \ + uw_pop_frame(&_h_n_d); \ + uw_catch(_e_x, _e_x_a); \ + (void) _e_x_a; \ uw_unwind { } \ uw_catch_end; \ return _r_e_t; |