diff options
Diffstat (limited to 'data/vim/patches/8.1.1019')
-rw-r--r-- | data/vim/patches/8.1.1019 | 671 |
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 /// |