comparison src/userfunc.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 28605af12602
children f2445075dbeb
comparison
equal deleted inserted replaced
33612:0dd1e3a17f68 33613:31fb1a760ad6
6250 6250
6251 char_u *name = dr->dr_name; 6251 char_u *name = dr->dr_name;
6252 dr->dr_name = NULL; 6252 dr->dr_name = NULL;
6253 6253
6254 // If the deferred function is called after an exception, then only the 6254 // If the deferred function is called after an exception, then only the
6255 // first statement in the function will be executed. Save and restore 6255 // first statement in the function will be executed (because of the
6256 // the try/catch/throw exception state. 6256 // exception). So save and restore the try/catch/throw exception
6257 int save_trylevel = trylevel; 6257 // state.
6258 int save_did_throw = did_throw; 6258 exception_state_T estate;
6259 int save_need_rethrow = need_rethrow; 6259 exception_state_save(&estate);
6260 6260 exception_state_clear();
6261 trylevel = 0;
6262 did_throw = FALSE;
6263 need_rethrow = FALSE;
6264 6261
6265 call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe); 6262 call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
6266 6263
6267 trylevel = save_trylevel; 6264 exception_state_restore(&estate);
6268 did_throw = save_did_throw;
6269 need_rethrow = save_need_rethrow;
6270 6265
6271 clear_tv(&rettv); 6266 clear_tv(&rettv);
6272 vim_free(name); 6267 vim_free(name);
6273 for (int i = dr->dr_argcount - 1; i >= 0; --i) 6268 for (int i = dr->dr_argcount - 1; i >= 0; --i)
6274 clear_tv(&dr->dr_argvars[i]); 6269 clear_tv(&dr->dr_argvars[i]);