Mercurial > vim
comparison src/vim9execute.c @ 32274:83caf07aedd6 v9.0.1468
patch 9.0.1468: recursively calling :defer function if it does :qa
Commit: https://github.com/vim/vim/commit/a1f2b5ddc63d4e2b6ab047d8c839dd8477b36aba
Author: zeertzjq <zeertzjq@outlook.com>
Date: Tue Apr 18 21:04:53 2023 +0100
patch 9.0.1468: recursively calling :defer function if it does :qa
Problem: Recursively calling :defer function if it does :qa in a compiled
function.
Solution: Clear the defer entry before calling the function. (closes #12271)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 18 Apr 2023 22:15:04 +0200 |
parents | 012facc8e25c |
children | 2e07c2bb2f60 |
comparison
equal
deleted
inserted
replaced
32273:a7e63171cbfb | 32274:83caf07aedd6 |
---|---|
1061 listitem_T *arg_li = l->lv_first; | 1061 listitem_T *arg_li = l->lv_first; |
1062 typval_T *functv = &l->lv_first->li_tv; | 1062 typval_T *functv = &l->lv_first->li_tv; |
1063 int obj_off = functv->v_type == VAR_PARTIAL ? 1 : 0; | 1063 int obj_off = functv->v_type == VAR_PARTIAL ? 1 : 0; |
1064 int argcount = l->lv_len - 1 - obj_off; | 1064 int argcount = l->lv_len - 1 - obj_off; |
1065 | 1065 |
1066 if (functv->vval.v_string == NULL) | |
1067 // already being called, can happen if function does ":qa" | |
1068 continue; | |
1069 | |
1066 if (obj_off == 1) | 1070 if (obj_off == 1) |
1067 arg_li = arg_li->li_next; // second list item is the object | 1071 arg_li = arg_li->li_next; // second list item is the object |
1068 for (i = 0; i < argcount; ++i) | 1072 for (i = 0; i < argcount; ++i) |
1069 { | 1073 { |
1070 arg_li = arg_li->li_next; | 1074 arg_li = arg_li->li_next; |
1080 funcexe.fe_partial = functv->vval.v_partial; | 1084 funcexe.fe_partial = functv->vval.v_partial; |
1081 funcexe.fe_object = l->lv_first->li_next->li_tv.vval.v_object; | 1085 funcexe.fe_object = l->lv_first->li_next->li_tv.vval.v_object; |
1082 if (funcexe.fe_object != NULL) | 1086 if (funcexe.fe_object != NULL) |
1083 ++funcexe.fe_object->obj_refcount; | 1087 ++funcexe.fe_object->obj_refcount; |
1084 } | 1088 } |
1085 (void)call_func(functv->vval.v_string, -1, | 1089 |
1086 &rettv, argcount, argvars, &funcexe); | 1090 char_u *name = functv->vval.v_string; |
1091 functv->vval.v_string = NULL; | |
1092 | |
1093 (void)call_func(name, -1, &rettv, argcount, argvars, &funcexe); | |
1094 | |
1087 clear_tv(&rettv); | 1095 clear_tv(&rettv); |
1096 vim_free(name); | |
1088 } | 1097 } |
1089 } | 1098 } |
1090 | 1099 |
1091 /* | 1100 /* |
1092 * Return from the current function. | 1101 * Return from the current function. |