mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #21450 from zeertzjq/vim-8.2.1210
vim-patch:8.2.{1208,1209,1210}: using ht_used when looping through a hashtab is less reliable
This commit is contained in:
commit
2d8bbe468e
@ -1297,7 +1297,7 @@ void free_all_functions(void)
|
|||||||
ufunc_T *fp;
|
ufunc_T *fp;
|
||||||
uint64_t skipped = 0;
|
uint64_t skipped = 0;
|
||||||
uint64_t todo = 1;
|
uint64_t todo = 1;
|
||||||
uint64_t used;
|
int changed;
|
||||||
|
|
||||||
// Clean up the current_funccal chain and the funccal stack.
|
// Clean up the current_funccal chain and the funccal stack.
|
||||||
while (current_funccal != NULL) {
|
while (current_funccal != NULL) {
|
||||||
@ -1321,9 +1321,9 @@ void free_all_functions(void)
|
|||||||
if (func_name_refcount((char_u *)fp->uf_name)) {
|
if (func_name_refcount((char_u *)fp->uf_name)) {
|
||||||
skipped++;
|
skipped++;
|
||||||
} else {
|
} else {
|
||||||
used = func_hashtab.ht_used;
|
changed = func_hashtab.ht_changed;
|
||||||
func_clear(fp, true);
|
func_clear(fp, true);
|
||||||
if (used != func_hashtab.ht_used) {
|
if (changed != func_hashtab.ht_changed) {
|
||||||
skipped = 0;
|
skipped = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1993,8 +1993,8 @@ char *save_function_name(char **name, bool skip, int flags, funcdict_T *fudi)
|
|||||||
/// Otherwise functions matching "regmatch".
|
/// Otherwise functions matching "regmatch".
|
||||||
static void list_functions(regmatch_T *regmatch)
|
static void list_functions(regmatch_T *regmatch)
|
||||||
{
|
{
|
||||||
const size_t used = func_hashtab.ht_used;
|
const int changed = func_hashtab.ht_changed;
|
||||||
size_t todo = used;
|
size_t todo = func_hashtab.ht_used;
|
||||||
const hashitem_T *const ht_array = func_hashtab.ht_array;
|
const hashitem_T *const ht_array = func_hashtab.ht_array;
|
||||||
|
|
||||||
for (const hashitem_T *hi = ht_array; todo > 0 && !got_int; hi++) {
|
for (const hashitem_T *hi = ht_array; todo > 0 && !got_int; hi++) {
|
||||||
@ -2008,7 +2008,7 @@ static void list_functions(regmatch_T *regmatch)
|
|||||||
: (!isdigit(*fp->uf_name)
|
: (!isdigit(*fp->uf_name)
|
||||||
&& vim_regexec(regmatch, (char *)fp->uf_name, 0)))) {
|
&& vim_regexec(regmatch, (char *)fp->uf_name, 0)))) {
|
||||||
list_func_head(fp, false, false);
|
list_func_head(fp, false, false);
|
||||||
if (used != func_hashtab.ht_used || ht_array != func_hashtab.ht_array) {
|
if (changed != func_hashtab.ht_changed) {
|
||||||
emsg(_("E454: function list was modified"));
|
emsg(_("E454: function list was modified"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2730,15 +2730,17 @@ bool function_exists(const char *const name, bool no_deref)
|
|||||||
char *get_user_func_name(expand_T *xp, int idx)
|
char *get_user_func_name(expand_T *xp, int idx)
|
||||||
{
|
{
|
||||||
static size_t done;
|
static size_t done;
|
||||||
|
static int changed;
|
||||||
static hashitem_T *hi;
|
static hashitem_T *hi;
|
||||||
ufunc_T *fp;
|
ufunc_T *fp;
|
||||||
|
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
done = 0;
|
done = 0;
|
||||||
hi = func_hashtab.ht_array;
|
hi = func_hashtab.ht_array;
|
||||||
|
changed = func_hashtab.ht_changed;
|
||||||
}
|
}
|
||||||
assert(hi);
|
assert(hi);
|
||||||
if (done < func_hashtab.ht_used) {
|
if (changed == func_hashtab.ht_changed && done < func_hashtab.ht_used) {
|
||||||
if (done++ > 0) {
|
if (done++ > 0) {
|
||||||
hi++;
|
hi++;
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,7 @@ int hash_add(hashtab_T *ht, char *key)
|
|||||||
void hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash)
|
void hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash)
|
||||||
{
|
{
|
||||||
ht->ht_used++;
|
ht->ht_used++;
|
||||||
|
ht->ht_changed++;
|
||||||
if (hi->hi_key == NULL) {
|
if (hi->hi_key == NULL) {
|
||||||
ht->ht_filled++;
|
ht->ht_filled++;
|
||||||
}
|
}
|
||||||
@ -242,6 +243,7 @@ void hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash)
|
|||||||
void hash_remove(hashtab_T *ht, hashitem_T *hi)
|
void hash_remove(hashtab_T *ht, hashitem_T *hi)
|
||||||
{
|
{
|
||||||
ht->ht_used--;
|
ht->ht_used--;
|
||||||
|
ht->ht_changed++;
|
||||||
hi->hi_key = HI_KEY_REMOVED;
|
hi->hi_key = HI_KEY_REMOVED;
|
||||||
hash_may_resize(ht, 0);
|
hash_may_resize(ht, 0);
|
||||||
}
|
}
|
||||||
@ -384,6 +386,7 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
|
|||||||
ht->ht_array = newarray;
|
ht->ht_array = newarray;
|
||||||
ht->ht_mask = newmask;
|
ht->ht_mask = newmask;
|
||||||
ht->ht_filled = ht->ht_used;
|
ht->ht_filled = ht->ht_used;
|
||||||
|
ht->ht_changed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HASH_CYCLE_BODY(hash, p) \
|
#define HASH_CYCLE_BODY(hash, p) \
|
||||||
|
@ -61,14 +61,15 @@ typedef struct hashitem_S {
|
|||||||
///
|
///
|
||||||
/// The hashtable grows to accommodate more entries when needed.
|
/// The hashtable grows to accommodate more entries when needed.
|
||||||
typedef struct hashtable_S {
|
typedef struct hashtable_S {
|
||||||
hash_T ht_mask; /// mask used for hash value
|
hash_T ht_mask; ///< mask used for hash value
|
||||||
/// (nr of items in array is "ht_mask" + 1)
|
///< (nr of items in array is "ht_mask" + 1)
|
||||||
size_t ht_used; /// number of items used
|
size_t ht_used; ///< number of items used
|
||||||
size_t ht_filled; /// number of items used or removed
|
size_t ht_filled; ///< number of items used or removed
|
||||||
int ht_locked; /// counter for hash_lock()
|
int ht_changed; ///< incremented when adding or removing an item
|
||||||
hashitem_T *ht_array; /// points to the array, allocated when it's
|
int ht_locked; ///< counter for hash_lock()
|
||||||
/// not "ht_smallarray"
|
hashitem_T *ht_array; ///< points to the array, allocated when it's
|
||||||
hashitem_T ht_smallarray[HT_INIT_SIZE]; /// initial array
|
///< not "ht_smallarray"
|
||||||
|
hashitem_T ht_smallarray[HT_INIT_SIZE]; ///< initial array
|
||||||
} hashtab_T;
|
} hashtab_T;
|
||||||
|
|
||||||
/// Iterate over a hashtab
|
/// Iterate over a hashtab
|
||||||
|
Loading…
Reference in New Issue
Block a user