Mercurial > vim
comparison src/time.c @ 33613:31fb1a760ad6 v9.0.2050
patch 9.0.2050: Vim9: crash with deferred function call and exception
Commit: https://github.com/vim/vim/commit/c59c1e0d88651a71ece7366e418f1253abbe2a28
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Thu Oct 19 10:52:34 2023 +0200
patch 9.0.2050: Vim9: crash with deferred function call and exception
Problem: Vim9: crash with deferred function call and exception
Solution: Save and restore exception state
Crash when a deferred function is called after an exception and another
exception is thrown
closes: #13376
closes: #13377
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 19 Oct 2023 11:00:07 +0200 |
parents | 673dcbaded32 |
children |
comparison
equal
deleted
inserted
replaced
33612:0dd1e3a17f68 | 33613:31fb1a760ad6 |
---|---|
559 int save_vgetc_busy = vgetc_busy; | 559 int save_vgetc_busy = vgetc_busy; |
560 int save_did_emsg = did_emsg; | 560 int save_did_emsg = did_emsg; |
561 int prev_uncaught_emsg = uncaught_emsg; | 561 int prev_uncaught_emsg = uncaught_emsg; |
562 int save_called_emsg = called_emsg; | 562 int save_called_emsg = called_emsg; |
563 int save_must_redraw = must_redraw; | 563 int save_must_redraw = must_redraw; |
564 int save_trylevel = trylevel; | |
565 int save_did_throw = did_throw; | |
566 int save_need_rethrow = need_rethrow; | |
567 int save_ex_pressedreturn = get_pressedreturn(); | 564 int save_ex_pressedreturn = get_pressedreturn(); |
568 int save_may_garbage_collect = may_garbage_collect; | 565 int save_may_garbage_collect = may_garbage_collect; |
569 except_T *save_current_exception = current_exception; | 566 vimvars_save_T vvsave; |
570 vimvars_save_T vvsave; | 567 exception_state_T estate; |
568 | |
569 exception_state_save(&estate); | |
571 | 570 |
572 // Create a scope for running the timer callback, ignoring most of | 571 // Create a scope for running the timer callback, ignoring most of |
573 // the current scope, such as being inside a try/catch. | 572 // the current scope, such as being inside a try/catch. |
574 timer_busy = timer_busy > 0 || vgetc_busy > 0; | 573 timer_busy = timer_busy > 0 || vgetc_busy > 0; |
575 vgetc_busy = 0; | 574 vgetc_busy = 0; |
576 called_emsg = 0; | 575 called_emsg = 0; |
577 did_emsg = FALSE; | 576 did_emsg = FALSE; |
578 must_redraw = 0; | 577 must_redraw = 0; |
579 trylevel = 0; | |
580 did_throw = FALSE; | |
581 need_rethrow = FALSE; | |
582 current_exception = NULL; | |
583 may_garbage_collect = FALSE; | 578 may_garbage_collect = FALSE; |
579 exception_state_clear(); | |
584 save_vimvars(&vvsave); | 580 save_vimvars(&vvsave); |
585 | 581 |
586 // Invoke the callback. | 582 // Invoke the callback. |
587 timer->tr_firing = TRUE; | 583 timer->tr_firing = TRUE; |
588 timer_callback(timer); | 584 timer_callback(timer); |
595 vgetc_busy = save_vgetc_busy; | 591 vgetc_busy = save_vgetc_busy; |
596 if (uncaught_emsg > prev_uncaught_emsg) | 592 if (uncaught_emsg > prev_uncaught_emsg) |
597 ++timer->tr_emsg_count; | 593 ++timer->tr_emsg_count; |
598 did_emsg = save_did_emsg; | 594 did_emsg = save_did_emsg; |
599 called_emsg = save_called_emsg; | 595 called_emsg = save_called_emsg; |
600 trylevel = save_trylevel; | 596 exception_state_restore(&estate); |
601 did_throw = save_did_throw; | |
602 need_rethrow = save_need_rethrow; | |
603 current_exception = save_current_exception; | |
604 restore_vimvars(&vvsave); | 597 restore_vimvars(&vvsave); |
605 if (must_redraw != 0) | 598 if (must_redraw != 0) |
606 need_update_screen = TRUE; | 599 need_update_screen = TRUE; |
607 must_redraw = must_redraw > save_must_redraw | 600 must_redraw = must_redraw > save_must_redraw |
608 ? must_redraw : save_must_redraw; | 601 ? must_redraw : save_must_redraw; |