Skip to content

Commit 01c9e10

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 5009946 + 0e5d3a2 commit 01c9e10

3 files changed

Lines changed: 46 additions & 22 deletions

File tree

src/testdir/test_partial.vim

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,22 +260,25 @@ func Test_cyclic_dict_arg()
260260
unlet Pt
261261
endfunc
262262

263-
func Ignored(job1, job2, status)
263+
func Ignored3(job1, job2, status)
264264
endfunc
265265

266266
func Test_cycle_partial_job()
267267
if has('job')
268268
let job = job_start('echo')
269-
call job_setoptions(job, {'exit_cb': function('Ignored', [job])})
269+
call job_setoptions(job, {'exit_cb': function('Ignored3', [job])})
270270
unlet job
271271
endif
272272
endfunc
273273

274+
func Ignored2(job, status)
275+
endfunc
276+
274277
func Test_ref_job_partial_dict()
275278
if has('job')
276279
let g:ref_job = job_start('echo')
277280
let d = {'a': 'b'}
278-
call job_setoptions(g:ref_job, {'exit_cb': function('string', [], d)})
281+
call job_setoptions(g:ref_job, {'exit_cb': function('Ignored2', [], d)})
279282
endif
280283
endfunc
281284

src/userfunc.c

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,22 +1099,53 @@ func_free(ufunc_T *fp, int force)
10991099
vim_free(fp);
11001100
}
11011101

1102+
/*
1103+
* There are two kinds of function names:
1104+
* 1. ordinary names, function defined with :function
1105+
* 2. numbered functions and lambdas
1106+
* For the first we only count the name stored in func_hashtab as a reference,
1107+
* using function() does not count as a reference, because the function is
1108+
* looked up by name.
1109+
*/
1110+
static int
1111+
func_name_refcount(char_u *name)
1112+
{
1113+
return isdigit(*name) || *name == '<';
1114+
}
1115+
11021116
#if defined(EXITFREE) || defined(PROTO)
11031117
void
11041118
free_all_functions(void)
11051119
{
11061120
hashitem_T *hi;
1121+
ufunc_T *fp;
1122+
long_u skipped = 0;
1123+
long_u todo;
11071124

11081125
/* Need to start all over every time, because func_free() may change the
11091126
* hash table. */
1110-
while (func_hashtab.ht_used > 0)
1111-
for (hi = func_hashtab.ht_array; ; ++hi)
1127+
while (func_hashtab.ht_used > skipped)
1128+
{
1129+
todo = func_hashtab.ht_used;
1130+
for (hi = func_hashtab.ht_array; todo > 0; ++hi)
11121131
if (!HASHITEM_EMPTY(hi))
11131132
{
1114-
func_free(HI2UF(hi), TRUE);
1115-
break;
1133+
--todo;
1134+
/* Only free functions that are not refcounted, those are
1135+
* supposed to be freed when no longer referenced. */
1136+
fp = HI2UF(hi);
1137+
if (func_name_refcount(fp->uf_name))
1138+
++skipped;
1139+
else
1140+
{
1141+
func_free(fp, TRUE);
1142+
skipped = 0;
1143+
break;
1144+
}
11161145
}
1117-
hash_clear(&func_hashtab);
1146+
}
1147+
if (skipped == 0)
1148+
hash_clear(&func_hashtab);
11181149
}
11191150
#endif
11201151

@@ -1668,20 +1699,6 @@ trans_function_name(
16681699
return name;
16691700
}
16701701

1671-
/*
1672-
* There are two kinds of function names:
1673-
* 1. ordinary names, function defined with :function
1674-
* 2. numbered functions and lambdas
1675-
* For the first we only count the name stored in func_hashtab as a reference,
1676-
* using function() does not count as a reference, because the function is
1677-
* looked up by name.
1678-
*/
1679-
static int
1680-
func_name_refcount(char_u *name)
1681-
{
1682-
return isdigit(*name) || *name == '<';
1683-
}
1684-
16851702
/*
16861703
* ":function"
16871704
*/

src/version.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,10 @@ static char *(features[]) =
778778

779779
static int included_patches[] =
780780
{ /* Add new patch number below this line */
781+
/**/
782+
2198,
783+
/**/
784+
2197,
781785
/**/
782786
2196,
783787
/**/

0 commit comments

Comments
 (0)