mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -415,7 +415,7 @@ WINDRES_CC = $(CC)
|
||||
###########################################################################
|
||||
|
||||
CFLAGS = -Iproto $(DEFINES) -pipe -march=$(ARCH) -Wall
|
||||
CXXFLAGS = -std=c++11
|
||||
CXXFLAGS = -std=gnu++11
|
||||
WINDRES_FLAGS = --preprocessor="$(WINDRES_CC) -E -xc" -DRC_INVOKED
|
||||
EXTRA_LIBS =
|
||||
|
||||
|
||||
+54
-31
@@ -209,7 +209,9 @@ static hashtab_T func_hashtab;
|
||||
/* The names of packages that once were loaded are remembered. */
|
||||
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
|
||||
|
||||
/* list heads for garbage collection */
|
||||
/* List heads for garbage collection. Although there can be a reference loop
|
||||
* from partial to dict to partial, we don't need to keep track of the partial,
|
||||
* since it will get freed when the dict is unused and gets freed. */
|
||||
static dict_T *first_dict = NULL; /* list of all dicts */
|
||||
static list_T *first_list = NULL; /* list of all lists */
|
||||
|
||||
@@ -7130,9 +7132,14 @@ set_ref_in_item(
|
||||
list_T *ll;
|
||||
int abort = FALSE;
|
||||
|
||||
if (tv->v_type == VAR_DICT)
|
||||
if (tv->v_type == VAR_DICT || tv->v_type == VAR_PARTIAL)
|
||||
{
|
||||
dd = tv->vval.v_dict;
|
||||
if (tv->v_type == VAR_DICT)
|
||||
dd = tv->vval.v_dict;
|
||||
else if (tv->vval.v_partial != NULL)
|
||||
dd = tv->vval.v_partial->pt_dict;
|
||||
else
|
||||
dd = NULL;
|
||||
if (dd != NULL && dd->dv_copyID != copyID)
|
||||
{
|
||||
/* Didn't see this dict yet. */
|
||||
@@ -7184,6 +7191,32 @@ set_ref_in_item(
|
||||
return abort;
|
||||
}
|
||||
|
||||
static void
|
||||
partial_free(partial_T *pt, int free_dict)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pt->pt_argc; ++i)
|
||||
clear_tv(&pt->pt_argv[i]);
|
||||
vim_free(pt->pt_argv);
|
||||
if (free_dict)
|
||||
dict_unref(pt->pt_dict);
|
||||
func_unref(pt->pt_name);
|
||||
vim_free(pt->pt_name);
|
||||
vim_free(pt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unreference a closure: decrement the reference count and free it when it
|
||||
* becomes zero.
|
||||
*/
|
||||
void
|
||||
partial_unref(partial_T *pt)
|
||||
{
|
||||
if (pt != NULL && --pt->pt_refcount <= 0)
|
||||
partial_free(pt, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an empty header for a dictionary.
|
||||
*/
|
||||
@@ -7275,7 +7308,18 @@ dict_free(
|
||||
hash_remove(&d->dv_hashtab, hi);
|
||||
if (recurse || (di->di_tv.v_type != VAR_LIST
|
||||
&& di->di_tv.v_type != VAR_DICT))
|
||||
clear_tv(&di->di_tv);
|
||||
{
|
||||
if (!recurse && di->di_tv.v_type == VAR_PARTIAL)
|
||||
{
|
||||
partial_T *pt = di->di_tv.vval.v_partial;
|
||||
|
||||
/* We unref the partial but not the dict it refers to. */
|
||||
if (pt != NULL && --pt->pt_refcount == 0)
|
||||
partial_free(pt, FALSE);
|
||||
}
|
||||
else
|
||||
clear_tv(&di->di_tv);
|
||||
}
|
||||
vim_free(di);
|
||||
--todo;
|
||||
}
|
||||
@@ -12011,30 +12055,6 @@ f_function(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
partial_free(partial_T *pt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pt->pt_argc; ++i)
|
||||
clear_tv(&pt->pt_argv[i]);
|
||||
vim_free(pt->pt_argv);
|
||||
func_unref(pt->pt_name);
|
||||
vim_free(pt->pt_name);
|
||||
vim_free(pt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unreference a closure: decrement the reference count and free it when it
|
||||
* becomes zero.
|
||||
*/
|
||||
void
|
||||
partial_unref(partial_T *pt)
|
||||
{
|
||||
if (pt != NULL && --pt->pt_refcount <= 0)
|
||||
partial_free(pt);
|
||||
}
|
||||
|
||||
/*
|
||||
* "garbagecollect()" function
|
||||
*/
|
||||
@@ -21824,7 +21844,8 @@ handle_subscript(
|
||||
selfdict = NULL;
|
||||
if (rettv->v_type == VAR_FUNC)
|
||||
{
|
||||
/* just a function: use selfdict */
|
||||
/* Just a function: Take over the function name and use
|
||||
* selfdict. */
|
||||
pt->pt_name = rettv->vval.v_string;
|
||||
}
|
||||
else
|
||||
@@ -21832,8 +21853,11 @@ handle_subscript(
|
||||
partial_T *ret_pt = rettv->vval.v_partial;
|
||||
int i;
|
||||
|
||||
/* partial: use selfdict and copy args */
|
||||
/* Partial: copy the function name, use selfdict and copy
|
||||
* args. Can't take over name or args, the partial might
|
||||
* be referenced elsewhere. */
|
||||
pt->pt_name = vim_strsave(ret_pt->pt_name);
|
||||
func_ref(pt->pt_name);
|
||||
if (ret_pt->pt_argc > 0)
|
||||
{
|
||||
pt->pt_argv = (typval_T *)alloc(
|
||||
@@ -21850,7 +21874,6 @@ handle_subscript(
|
||||
}
|
||||
partial_unref(ret_pt);
|
||||
}
|
||||
func_ref(pt->pt_name);
|
||||
rettv->v_type = VAR_PARTIAL;
|
||||
rettv->vval.v_partial = pt;
|
||||
}
|
||||
|
||||
@@ -1997,6 +1997,7 @@ getcmdline_prompt(
|
||||
char_u *s;
|
||||
struct cmdline_info save_ccline;
|
||||
int msg_col_save = msg_col;
|
||||
int msg_silent_save = msg_silent;
|
||||
|
||||
save_cmdline(&save_ccline);
|
||||
ccline.cmdprompt = prompt;
|
||||
@@ -2006,8 +2007,10 @@ getcmdline_prompt(
|
||||
ccline.xp_arg = xp_arg;
|
||||
ccline.input_fn = (firstc == '@');
|
||||
# endif
|
||||
msg_silent = 0;
|
||||
s = getcmdline(firstc, 1L, 0);
|
||||
restore_cmdline(&save_ccline);
|
||||
msg_silent = msg_silent_save;
|
||||
/* Restore msg_col, the prompt from input() may have changed it.
|
||||
* But only if called recursively and the commandline is therefore being
|
||||
* restored to an old one; if not, the input() prompt stays on the screen,
|
||||
|
||||
@@ -170,3 +170,13 @@ func Test_partial_string()
|
||||
let F = function('MyFunc', ['foo'], d)
|
||||
call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F))
|
||||
endfunc
|
||||
|
||||
func Test_func_unref()
|
||||
let obj = {}
|
||||
function! obj.func() abort
|
||||
endfunction
|
||||
let funcnumber = matchstr(string(obj.func), '^function(''\zs.\{-}\ze''')
|
||||
call assert_true(exists('*{' . funcnumber . '}'))
|
||||
unlet obj
|
||||
call assert_false(exists('*{' . funcnumber . '}'))
|
||||
endfunc
|
||||
|
||||
@@ -763,6 +763,14 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1639,
|
||||
/**/
|
||||
1638,
|
||||
/**/
|
||||
1637,
|
||||
/**/
|
||||
1636,
|
||||
/**/
|
||||
1635,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user