diff --git a/i/c/motes.h b/i/c/motes.h index 5c86c8e81f..557c7c088c 100644 --- a/i/c/motes.h +++ b/i/c/motes.h @@ -886,6 +886,7 @@ # define c3__scry c3_s4('s','c','r','y') # define c3__scsg c3_s4('s','c','s','g') # define c3__seal c3_s4('s','e','a','l') +# define c3__seat c3_s4('s','e','a','t') # define c3__see c3_s3('s','e','e') # define c3__seed c3_s4('s','e','e','d') # define c3__seek c3_s4('s','e','e','k') diff --git a/n/m.c b/n/m.c index 08a09326ca..891f0518c4 100644 --- a/n/m.c +++ b/n/m.c @@ -188,6 +188,47 @@ _cm_signal_reset(void) u3R->kid_u = 0; } +/* _cm_stack_recover(): recover stack trace, with lacunae. +*/ +static u3_noun +_cm_stack_recover(u3a_road* rod_u) +{ + c3_w len_w; + + len_w = 0; + { + u3_noun tax = rod_u->bug.tax; + + while ( tax ) { + len_w++; + tax = u3t(tax); + } + + if ( len_w < 4096 ) { + return u3a_take(rod_u->bug.tax); + } + else { + u3_noun beg, fin; + c3_w i_w; + + tax = rod_u->bug.tax; + beg = u3_nul; + for ( i_w = 0; i_w < 2048; i_w++ ) { + beg = u3nc(u3a_take(u3h(tax)), beg); + tax = u3t(tax); + } + beg = u3kb_flop(beg); + + for ( i_w = 0; i_w < (len_w - 4096); i_w++ ) { + tax = u3t(tax); + } + fin = u3nc(u3nc(c3__lose, c3__over), u3a_take(tax)); + + return u3kb_weld(beg, fin); + } + } +} + /* _cm_signal_recover(): recover from a deep signal, after longjmp. Free arg. */ static u3_noun @@ -235,9 +276,13 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg) u3R = &(u3H->rod_u); rod_u = u3R; - + while ( rod_u->kid_u ) { - tax = u3kb_weld(u3a_take(rod_u->kid_u->bug.tax), tax); +#if 0 + fprintf(stderr, "collecting %d frames\r\n", + u3kb_lent(rod_u->kid_u->bug.tax)); +#endif + tax = u3kb_weld(_cm_stack_recover(rod_u->kid_u), tax); rod_u = rod_u->kid_u; } } diff --git a/v/term.c b/v/term.c index 8114e165c2..83abf0cc1c 100644 --- a/v/term.c +++ b/v/term.c @@ -306,6 +306,7 @@ _term_listen_cb(uv_stream_t *wax_u, int sas_i) u3_noun pax = u3nq(u3_blip, c3__term, tid, u3_nul); u3v_plan(u3k(pax), u3nc(c3__blew, u3nc(80, 25))); u3v_plan(u3k(pax), u3nc(c3__hail, u3_nul)); + u3v_plan(u3k(pax), u3nq(c3__flow, c3__seat, c3__talk, u3_nul)); u3z(pax); } @@ -668,6 +669,17 @@ _term_it_save(u3_noun pax, u3_noun pad) free(pax_c); } +/* _term_io_flow(): send flow. +*/ +static void +_term_io_flow(u3_utty* uty_u) +{ + u3_noun tid = u3dc("scot", c3__ud, uty_u->tid_l); + u3_noun pax = u3nq(u3_blip, c3__term, tid, u3_nul); + + u3v_plan(pax, u3nq(c3__flow, c3__seat, c3__talk, u3_nul)); +} + /* _term_io_belt(): send belt. */ static void @@ -818,6 +830,9 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) else if ( 13 == cay_y ) { _term_io_belt(uty_u, u3nc(c3__ret, u3_nul)); } + else if ( 6 == cay_y ) { + _term_io_flow(uty_u); // XX hack + } else if ( cay_y <= 26 ) { _term_io_belt(uty_u, u3nc(c3__ctl, ('a' + (cay_y - 1)))); }