summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.1019
diff options
context:
space:
mode:
Diffstat (limited to 'data/vim/patches/8.1.1019')
-rw-r--r--data/vim/patches/8.1.1019671
1 files changed, 671 insertions, 0 deletions
diff --git a/data/vim/patches/8.1.1019 b/data/vim/patches/8.1.1019
new file mode 100644
index 000000000..013f436ae
--- /dev/null
+++ b/data/vim/patches/8.1.1019
@@ -0,0 +1,671 @@
+To: vim_dev@googlegroups.com
+Subject: Patch 8.1.1019
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 8.1.1019
+Problem: Lua: may garbage collect function reference in use.
+Solution: Keep the function name instead of the typeval. Make luaV_setref()
+ handle funcref objects. (Ozaki Kiichi, closes #4127)
+Files: src/if_lua.c, src/testdir/test_lua.vim
+
+
+*** ../vim-8.1.1018/src/if_lua.c 2019-03-16 16:38:37.560654505 +0100
+--- src/if_lua.c 2019-03-19 21:57:33.226164566 +0100
+***************
+*** 29,36 ****
+ typedef dict_T *luaV_Dict;
+ typedef list_T *luaV_List;
+ typedef struct {
+! typval_T tv; // funcref
+! typval_T args;
+ dict_T *self; // selfdict
+ } luaV_Funcref;
+ typedef void (*msgfunc_T)(char_u *);
+--- 29,35 ----
+ typedef dict_T *luaV_Dict;
+ typedef list_T *luaV_List;
+ typedef struct {
+! char_u *name; // funcref
+ dict_T *self; // selfdict
+ } luaV_Funcref;
+ typedef void (*msgfunc_T)(char_u *);
+***************
+*** 69,75 ****
+
+ static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
+ static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
+! static luaV_Funcref *luaV_pushfuncref(lua_State *L, typval_T *tv);
+
+ #if LUA_VERSION_NUM <= 501
+ #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
+--- 68,74 ----
+
+ static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
+ static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
+! static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
+
+ #if LUA_VERSION_NUM <= 501
+ #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
+***************
+*** 443,449 ****
+
+ #if LUA_VERSION_NUM > 501
+ static int
+! luaL_typeerror (lua_State *L, int narg, const char *tname)
+ {
+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
+ tname, luaL_typename(L, narg));
+--- 442,448 ----
+
+ #if LUA_VERSION_NUM > 501
+ static int
+! luaL_typeerror(lua_State *L, int narg, const char *tname)
+ {
+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
+ tname, luaL_typename(L, narg));
+***************
+*** 540,546 ****
+ lua_pushnil(L);
+ break;
+ case VAR_FUNC:
+! luaV_pushfuncref(L, tv);
+ break;
+ default:
+ lua_pushnil(L);
+--- 539,545 ----
+ lua_pushnil(L);
+ break;
+ case VAR_FUNC:
+! luaV_pushfuncref(L, tv->vval.v_string);
+ break;
+ default:
+ lua_pushnil(L);
+***************
+*** 610,616 ****
+ if (lua_rawequal(L, -1, -4))
+ {
+ luaV_Funcref *f = (luaV_Funcref *) p;
+! copy_tv(&f->tv, tv);
+ lua_pop(L, 4); /* MTs */
+ break;
+ }
+--- 609,617 ----
+ if (lua_rawequal(L, -1, -4))
+ {
+ luaV_Funcref *f = (luaV_Funcref *) p;
+! func_ref(f->name);
+! tv->v_type = VAR_FUNC;
+! tv->vval.v_string = vim_strsave(f->name);
+ lua_pop(L, 4); /* MTs */
+ break;
+ }
+***************
+*** 693,699 ****
+
+ #define luaV_newtype(typ,tname,luatyp,luatname) \
+ static luatyp * \
+! luaV_new##tname (lua_State *L, typ *obj) \
+ { \
+ luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
+ *o = obj; \
+--- 694,700 ----
+
+ #define luaV_newtype(typ,tname,luatyp,luatname) \
+ static luatyp * \
+! luaV_new##tname(lua_State *L, typ *obj) \
+ { \
+ luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
+ *o = obj; \
+***************
+*** 725,731 ****
+
+ #define luaV_type_tostring(tname,luatname) \
+ static int \
+! luaV_##tname##_tostring (lua_State *L) \
+ { \
+ lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
+ return 1; \
+--- 726,732 ----
+
+ #define luaV_type_tostring(tname,luatname) \
+ static int \
+! luaV_##tname##_tostring(lua_State *L) \
+ { \
+ lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
+ return 1; \
+***************
+*** 734,740 ****
+ /* ======= List type ======= */
+
+ static luaV_List *
+! luaV_newlist (lua_State *L, list_T *lis)
+ {
+ luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
+ *l = lis;
+--- 735,741 ----
+ /* ======= List type ======= */
+
+ static luaV_List *
+! luaV_newlist(lua_State *L, list_T *lis)
+ {
+ luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
+ *l = lis;
+***************
+*** 749,755 ****
+ luaV_type_tostring(list, LUAVIM_LIST)
+
+ static int
+! luaV_list_len (lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len);
+--- 750,756 ----
+ luaV_type_tostring(list, LUAVIM_LIST)
+
+ static int
+! luaV_list_len(lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len);
+***************
+*** 757,763 ****
+ }
+
+ static int
+! luaV_list_iter (lua_State *L)
+ {
+ listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
+ if (li == NULL) return 0;
+--- 758,764 ----
+ }
+
+ static int
+! luaV_list_iter(lua_State *L)
+ {
+ listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
+ if (li == NULL) return 0;
+***************
+*** 768,774 ****
+ }
+
+ static int
+! luaV_list_call (lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
+--- 769,775 ----
+ }
+
+ static int
+! luaV_list_call(lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
+***************
+*** 778,784 ****
+ }
+
+ static int
+! luaV_list_index (lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ if (lua_isnumber(L, 2)) /* list item? */
+--- 779,785 ----
+ }
+
+ static int
+! luaV_list_index(lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ if (lua_isnumber(L, 2)) /* list item? */
+***************
+*** 807,813 ****
+ }
+
+ static int
+! luaV_list_newindex (lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ long n = (long) luaL_checkinteger(L, 2);
+--- 808,814 ----
+ }
+
+ static int
+! luaV_list_newindex(lua_State *L)
+ {
+ list_T *l = luaV_unbox(L, luaV_List, 1);
+ long n = (long) luaL_checkinteger(L, 2);
+***************
+*** 834,840 ****
+ }
+
+ static int
+! luaV_list_add (lua_State *L)
+ {
+ luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
+ list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
+--- 835,841 ----
+ }
+
+ static int
+! luaV_list_add(lua_State *L)
+ {
+ luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
+ list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
+***************
+*** 851,857 ****
+ }
+
+ static int
+! luaV_list_insert (lua_State *L)
+ {
+ luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
+ list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
+--- 852,858 ----
+ }
+
+ static int
+! luaV_list_insert(lua_State *L)
+ {
+ luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
+ list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
+***************
+*** 890,896 ****
+ /* ======= Dict type ======= */
+
+ static luaV_Dict *
+! luaV_newdict (lua_State *L, dict_T *dic)
+ {
+ luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
+ *d = dic;
+--- 891,897 ----
+ /* ======= Dict type ======= */
+
+ static luaV_Dict *
+! luaV_newdict(lua_State *L, dict_T *dic)
+ {
+ luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
+ *d = dic;
+***************
+*** 905,911 ****
+ luaV_type_tostring(dict, LUAVIM_DICT)
+
+ static int
+! luaV_dict_len (lua_State *L)
+ {
+ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
+ lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used);
+--- 906,912 ----
+ luaV_type_tostring(dict, LUAVIM_DICT)
+
+ static int
+! luaV_dict_len(lua_State *L)
+ {
+ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
+ lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used);
+***************
+*** 913,919 ****
+ }
+
+ static int
+! luaV_dict_iter (lua_State *L UNUSED)
+ {
+ #ifdef FEAT_EVAL
+ hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
+--- 914,920 ----
+ }
+
+ static int
+! luaV_dict_iter(lua_State *L UNUSED)
+ {
+ #ifdef FEAT_EVAL
+ hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
+***************
+*** 935,941 ****
+ }
+
+ static int
+! luaV_dict_call (lua_State *L)
+ {
+ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
+ hashtab_T *ht = &d->dv_hashtab;
+--- 936,942 ----
+ }
+
+ static int
+! luaV_dict_call(lua_State *L)
+ {
+ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
+ hashtab_T *ht = &d->dv_hashtab;
+***************
+*** 1037,1047 ****
+
+ if (name != NULL)
+ {
+! func_ref(name); /* as in copy_tv */
+! f->tv.vval.v_string = vim_strsave(name);
+ }
+- f->tv.v_type = VAR_FUNC;
+- f->args.v_type = VAR_LIST;
+ f->self = NULL;
+ luaV_getfield(L, LUAVIM_FUNCREF);
+ lua_setmetatable(L, -2);
+--- 1038,1046 ----
+
+ if (name != NULL)
+ {
+! func_ref(name);
+! f->name = vim_strsave(name);
+ }
+ f->self = NULL;
+ luaV_getfield(L, LUAVIM_FUNCREF);
+ lua_setmetatable(L, -2);
+***************
+*** 1049,1060 ****
+ }
+
+ static luaV_Funcref *
+! luaV_pushfuncref(lua_State *L, typval_T *tv)
+ {
+! luaV_Funcref *f = luaV_newfuncref(L, NULL);
+! copy_tv(tv, &f->tv);
+! clear_tv(tv);
+! return f;
+ }
+
+
+--- 1048,1056 ----
+ }
+
+ static luaV_Funcref *
+! luaV_pushfuncref(lua_State *L, char_u *name)
+ {
+! return luaV_newfuncref(L, name);
+ }
+
+
+***************
+*** 1065,1073 ****
+ {
+ luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
+
+! func_unref(f->tv.vval.v_string);
+! vim_free(f->tv.vval.v_string);
+! dict_unref(f->self);
+ return 0;
+ }
+
+--- 1061,1070 ----
+ {
+ luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
+
+! func_unref(f->name);
+! vim_free(f->name);
+! // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self"
+! // will be (or has been already) freed by Vim's garbage collection.
+ return 0;
+ }
+
+***************
+*** 1077,1083 ****
+ {
+ luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
+
+! lua_pushstring(L, (const char *) f->tv.vval.v_string);
+ return 1;
+ }
+
+--- 1074,1080 ----
+ {
+ luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
+
+! lua_pushstring(L, (const char *) f->name);
+ return 1;
+ }
+
+***************
+*** 1085,1111 ****
+ luaV_funcref_call(lua_State *L)
+ {
+ luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
+! int i, n = lua_gettop(L) - 1; /* #args */
+! int status;
+! typval_T v, rettv;
+!
+! f->args.vval.v_list = list_alloc();
+! rettv.v_type = VAR_UNKNOWN; /* as in clear_tv */
+! if (f->args.vval.v_list == NULL)
+! status = FAIL;
+! else
+ {
+ for (i = 0; i < n; i++)
+ {
+ luaV_checktypval(L, i + 2, &v, "calling funcref");
+! list_append_tv(f->args.vval.v_list, &v);
+ clear_tv(&v);
+ }
+! status = func_call(f->tv.vval.v_string, &f->args,
+! NULL, f->self, &rettv);
+ if (status == OK)
+ luaV_pushtypval(L, &rettv);
+! clear_tv(&f->args);
+ clear_tv(&rettv);
+ }
+ if (status != OK)
+--- 1082,1109 ----
+ luaV_funcref_call(lua_State *L)
+ {
+ luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
+! int i, n = lua_gettop(L) - 1; // #args
+! int status = FAIL;
+! typval_T args;
+! typval_T rettv;
+!
+! args.v_type = VAR_LIST;
+! args.vval.v_list = list_alloc();
+! rettv.v_type = VAR_UNKNOWN; // as in clear_tv
+! if (args.vval.v_list != NULL)
+ {
++ typval_T v;
++
+ for (i = 0; i < n; i++)
+ {
+ luaV_checktypval(L, i + 2, &v, "calling funcref");
+! list_append_tv(args.vval.v_list, &v);
+ clear_tv(&v);
+ }
+! status = func_call(f->name, &args, NULL, f->self, &rettv);
+ if (status == OK)
+ luaV_pushtypval(L, &rettv);
+! clear_tv(&args);
+ clear_tv(&rettv);
+ }
+ if (status != OK)
+***************
+*** 1368,1374 ****
+ }
+
+ static int
+! luaV_window_newindex (lua_State *L)
+ {
+ win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
+ const char *s = luaL_checkstring(L, 2);
+--- 1366,1372 ----
+ }
+
+ static int
+! luaV_window_newindex(lua_State *L)
+ {
+ win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
+ const char *s = luaL_checkstring(L, 2);
+***************
+*** 1768,1774 ****
+ }
+
+ static int
+! luaV_luaeval (lua_State *L)
+ {
+ luaL_Buffer b;
+ size_t l;
+--- 1766,1772 ----
+ }
+
+ static int
+! luaV_luaeval(lua_State *L)
+ {
+ luaL_Buffer b;
+ size_t l;
+***************
+*** 1797,1828 ****
+ }
+
+ static int
+! luaV_setref (lua_State *L)
+ {
+! int copyID = lua_tointeger(L, 1);
+! int abort = FALSE;
+! typval_T tv;
+
+ luaV_getfield(L, LUAVIM_LIST);
+ luaV_getfield(L, LUAVIM_DICT);
+ lua_pushnil(L);
+! /* traverse cache table */
+ while (!abort && lua_next(L, lua_upvalueindex(1)) != 0)
+ {
+ lua_getmetatable(L, -1);
+! if (lua_rawequal(L, -1, 2)) /* list? */
+ {
+! tv.v_type = VAR_LIST;
+! tv.vval.v_list = (list_T *) lua_touserdata(L, 4); /* key */
+! abort = set_ref_in_item(&tv, copyID, NULL, NULL);
+ }
+! else if (lua_rawequal(L, -1, 3)) /* dict? */
+ {
+! tv.v_type = VAR_DICT;
+! tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */
+! abort = set_ref_in_item(&tv, copyID, NULL, NULL);
+ }
+! lua_pop(L, 2); /* metatable and value */
+ }
+ lua_pushinteger(L, abort);
+ return 1;
+--- 1795,1844 ----
+ }
+
+ static int
+! luaV_setref(lua_State *L)
+ {
+! int copyID = lua_tointeger(L, 1);
+! int abort = FALSE;
+
+ luaV_getfield(L, LUAVIM_LIST);
+ luaV_getfield(L, LUAVIM_DICT);
++ luaV_getfield(L, LUAVIM_FUNCREF);
+ lua_pushnil(L);
+! // traverse cache table
+ while (!abort && lua_next(L, lua_upvalueindex(1)) != 0)
+ {
+ lua_getmetatable(L, -1);
+! if (lua_rawequal(L, -1, 2)) // list?
+! {
+! list_T *l = (list_T *)lua_touserdata(L, 5); // key
+!
+! if (l->lv_copyID != copyID)
+! {
+! l->lv_copyID = copyID;
+! abort = set_ref_in_list(l, copyID, NULL);
+! }
+! }
+! else if (lua_rawequal(L, -1, 3)) // dict?
+ {
+! dict_T *d = (dict_T *)lua_touserdata(L, 5); // key
+!
+! if (d->dv_copyID != copyID)
+! {
+! d->dv_copyID = copyID;
+! abort = set_ref_in_ht(&d->dv_hashtab, copyID, NULL);
+! }
+ }
+! else if (lua_rawequal(L, -1, 4)) // funcref?
+ {
+! luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key
+!
+! if (f->self != NULL && f->self->dv_copyID != copyID)
+! {
+! f->self->dv_copyID = copyID;
+! abort = set_ref_in_ht(&f->self->dv_hashtab, copyID, NULL);
+! }
+ }
+! lua_pop(L, 2); // metatable and value
+ }
+ lua_pushinteger(L, abort);
+ return 1;
+***************
+*** 2053,2059 ****
+ luaV_freetype(win_T, window)
+
+ void
+! do_luaeval (char_u *str, typval_T *arg, typval_T *rettv)
+ {
+ lua_init();
+ luaV_getfield(L, LUAVIM_LUAEVAL);
+--- 2069,2075 ----
+ luaV_freetype(win_T, window)
+
+ void
+! do_luaeval(char_u *str, typval_T *arg, typval_T *rettv)
+ {
+ lua_init();
+ luaV_getfield(L, LUAVIM_LUAEVAL);
+***************
+*** 2064,2070 ****
+ }
+
+ int
+! set_ref_in_lua (int copyID)
+ {
+ int aborted = 0;
+
+--- 2080,2086 ----
+ }
+
+ int
+! set_ref_in_lua(int copyID)
+ {
+ int aborted = 0;
+
+*** ../vim-8.1.1018/src/testdir/test_lua.vim 2019-03-10 09:48:55.711808501 +0100
+--- src/testdir/test_lua.vim 2019-03-19 21:50:17.437605532 +0100
+***************
+*** 449,454 ****
+--- 449,455 ----
+ lua d.len = vim.funcref"Mylen" -- assign d as 'self'
+ lua res = (d.len() == vim.funcref"len"(vim.eval"l")) and "OK" or "FAIL"
+ call assert_equal("OK", luaeval('res'))
++ call assert_equal(function('Mylen', {'data': l, 'len': function('Mylen')}), mydict.len)
+
+ lua i1, i2, msg, d, res = nil
+ endfunc
+*** ../vim-8.1.1018/src/version.c 2019-03-19 20:50:40.290035255 +0100
+--- src/version.c 2019-03-19 21:53:59.151973880 +0100
+***************
+*** 781,782 ****
+--- 781,784 ----
+ { /* Add new patch number below this line */
++ /**/
++ 1019,
+ /**/
+
+--
+From "know your smileys":
+ :-O>-o Smiley American tourist (note big mouth and camera)
+
+ /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
+/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\ an exciting new programming language -- http://www.Zimbu.org ///
+ \\\ help me help AIDS victims -- http://ICCF-Holland.org ///