Mercurial > vim
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]); |