comparison src/if_lua.c @ 16028:8ad2cda3757d v8.1.1019

patch 8.1.1019: Lua: may garbage collect function reference in use commit https://github.com/vim/vim/commit/4eefe47ea4b6bf958617e924f52bc7a409cfb0ed Author: Bram Moolenaar <Bram@vim.org> Date: Tue Mar 19 21:59:19 2019 +0100 patch 8.1.1019: Lua: may garbage collect function reference in use 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)
author Bram Moolenaar <Bram@vim.org>
date Tue, 19 Mar 2019 22:00:07 +0100
parents 3b524e8110ab
children a2f0e93a5857
comparison
equal deleted inserted replaced
16027:d9cbab38f941 16028:8ad2cda3757d
27 typedef buf_T *luaV_Buffer; 27 typedef buf_T *luaV_Buffer;
28 typedef win_T *luaV_Window; 28 typedef win_T *luaV_Window;
29 typedef dict_T *luaV_Dict; 29 typedef dict_T *luaV_Dict;
30 typedef list_T *luaV_List; 30 typedef list_T *luaV_List;
31 typedef struct { 31 typedef struct {
32 typval_T tv; // funcref 32 char_u *name; // funcref
33 typval_T args;
34 dict_T *self; // selfdict 33 dict_T *self; // selfdict
35 } luaV_Funcref; 34 } luaV_Funcref;
36 typedef void (*msgfunc_T)(char_u *); 35 typedef void (*msgfunc_T)(char_u *);
37 36
38 static const char LUAVIM_DICT[] = "dict"; 37 static const char LUAVIM_DICT[] = "dict";
67 luaL_error(L, msg ": cannot convert value"); \ 66 luaL_error(L, msg ": cannot convert value"); \
68 } while (0) 67 } while (0)
69 68
70 static luaV_List *luaV_pushlist(lua_State *L, list_T *lis); 69 static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
71 static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic); 70 static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
72 static luaV_Funcref *luaV_pushfuncref(lua_State *L, typval_T *tv); 71 static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
73 72
74 #if LUA_VERSION_NUM <= 501 73 #if LUA_VERSION_NUM <= 501
75 #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n) 74 #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
76 #define luaL_typeerror luaL_typerror 75 #define luaL_typeerror luaL_typerror
77 #else 76 #else
441 } 440 }
442 #endif 441 #endif
443 442
444 #if LUA_VERSION_NUM > 501 443 #if LUA_VERSION_NUM > 501
445 static int 444 static int
446 luaL_typeerror (lua_State *L, int narg, const char *tname) 445 luaL_typeerror(lua_State *L, int narg, const char *tname)
447 { 446 {
448 const char *msg = lua_pushfstring(L, "%s expected, got %s", 447 const char *msg = lua_pushfstring(L, "%s expected, got %s",
449 tname, luaL_typename(L, narg)); 448 tname, luaL_typename(L, narg));
450 return luaL_argerror(L, narg, msg); 449 return luaL_argerror(L, narg, msg);
451 } 450 }
538 lua_pushinteger(L, (int) tv->vval.v_number); 537 lua_pushinteger(L, (int) tv->vval.v_number);
539 else 538 else
540 lua_pushnil(L); 539 lua_pushnil(L);
541 break; 540 break;
542 case VAR_FUNC: 541 case VAR_FUNC:
543 luaV_pushfuncref(L, tv); 542 luaV_pushfuncref(L, tv->vval.v_string);
544 break; 543 break;
545 default: 544 default:
546 lua_pushnil(L); 545 lua_pushnil(L);
547 } 546 }
548 } 547 }
608 /* check funcref */ 607 /* check funcref */
609 luaV_getfield(L, LUAVIM_FUNCREF); 608 luaV_getfield(L, LUAVIM_FUNCREF);
610 if (lua_rawequal(L, -1, -4)) 609 if (lua_rawequal(L, -1, -4))
611 { 610 {
612 luaV_Funcref *f = (luaV_Funcref *) p; 611 luaV_Funcref *f = (luaV_Funcref *) p;
613 copy_tv(&f->tv, tv); 612 func_ref(f->name);
613 tv->v_type = VAR_FUNC;
614 tv->vval.v_string = vim_strsave(f->name);
614 lua_pop(L, 4); /* MTs */ 615 lua_pop(L, 4); /* MTs */
615 break; 616 break;
616 } 617 }
617 lua_pop(L, 4); /* MTs */ 618 lua_pop(L, 4); /* MTs */
618 } 619 }
691 lua_pop(L, 2); /* original and modified strings */ 692 lua_pop(L, 2); /* original and modified strings */
692 } 693 }
693 694
694 #define luaV_newtype(typ,tname,luatyp,luatname) \ 695 #define luaV_newtype(typ,tname,luatyp,luatname) \
695 static luatyp * \ 696 static luatyp * \
696 luaV_new##tname (lua_State *L, typ *obj) \ 697 luaV_new##tname(lua_State *L, typ *obj) \
697 { \ 698 { \
698 luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \ 699 luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
699 *o = obj; \ 700 *o = obj; \
700 luaV_setudata(L, obj); /* cache[obj] = udata */ \ 701 luaV_setudata(L, obj); /* cache[obj] = udata */ \
701 luaV_getfield(L, luatname); \ 702 luaV_getfield(L, luatname); \
723 return o; \ 724 return o; \
724 } 725 }
725 726
726 #define luaV_type_tostring(tname,luatname) \ 727 #define luaV_type_tostring(tname,luatname) \
727 static int \ 728 static int \
728 luaV_##tname##_tostring (lua_State *L) \ 729 luaV_##tname##_tostring(lua_State *L) \
729 { \ 730 { \
730 lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \ 731 lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
731 return 1; \ 732 return 1; \
732 } 733 }
733 734
734 /* ======= List type ======= */ 735 /* ======= List type ======= */
735 736
736 static luaV_List * 737 static luaV_List *
737 luaV_newlist (lua_State *L, list_T *lis) 738 luaV_newlist(lua_State *L, list_T *lis)
738 { 739 {
739 luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List)); 740 luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
740 *l = lis; 741 *l = lis;
741 lis->lv_refcount++; /* reference in Lua */ 742 lis->lv_refcount++; /* reference in Lua */
742 luaV_setudata(L, lis); /* cache[lis] = udata */ 743 luaV_setudata(L, lis); /* cache[lis] = udata */
747 748
748 luaV_pushtype(list_T, list, luaV_List) 749 luaV_pushtype(list_T, list, luaV_List)
749 luaV_type_tostring(list, LUAVIM_LIST) 750 luaV_type_tostring(list, LUAVIM_LIST)
750 751
751 static int 752 static int
752 luaV_list_len (lua_State *L) 753 luaV_list_len(lua_State *L)
753 { 754 {
754 list_T *l = luaV_unbox(L, luaV_List, 1); 755 list_T *l = luaV_unbox(L, luaV_List, 1);
755 lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len); 756 lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len);
756 return 1; 757 return 1;
757 } 758 }
758 759
759 static int 760 static int
760 luaV_list_iter (lua_State *L) 761 luaV_list_iter(lua_State *L)
761 { 762 {
762 listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 763 listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
763 if (li == NULL) return 0; 764 if (li == NULL) return 0;
764 luaV_pushtypval(L, &li->li_tv); 765 luaV_pushtypval(L, &li->li_tv);
765 lua_pushlightuserdata(L, (void *) li->li_next); 766 lua_pushlightuserdata(L, (void *) li->li_next);
766 lua_replace(L, lua_upvalueindex(2)); 767 lua_replace(L, lua_upvalueindex(2));
767 return 1; 768 return 1;
768 } 769 }
769 770
770 static int 771 static int
771 luaV_list_call (lua_State *L) 772 luaV_list_call(lua_State *L)
772 { 773 {
773 list_T *l = luaV_unbox(L, luaV_List, 1); 774 list_T *l = luaV_unbox(L, luaV_List, 1);
774 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */ 775 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
775 lua_pushlightuserdata(L, (void *) l->lv_first); 776 lua_pushlightuserdata(L, (void *) l->lv_first);
776 lua_pushcclosure(L, luaV_list_iter, 2); 777 lua_pushcclosure(L, luaV_list_iter, 2);
777 return 1; 778 return 1;
778 } 779 }
779 780
780 static int 781 static int
781 luaV_list_index (lua_State *L) 782 luaV_list_index(lua_State *L)
782 { 783 {
783 list_T *l = luaV_unbox(L, luaV_List, 1); 784 list_T *l = luaV_unbox(L, luaV_List, 1);
784 if (lua_isnumber(L, 2)) /* list item? */ 785 if (lua_isnumber(L, 2)) /* list item? */
785 { 786 {
786 listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2)); 787 listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2));
805 lua_pushnil(L); 806 lua_pushnil(L);
806 return 1; 807 return 1;
807 } 808 }
808 809
809 static int 810 static int
810 luaV_list_newindex (lua_State *L) 811 luaV_list_newindex(lua_State *L)
811 { 812 {
812 list_T *l = luaV_unbox(L, luaV_List, 1); 813 list_T *l = luaV_unbox(L, luaV_List, 1);
813 long n = (long) luaL_checkinteger(L, 2); 814 long n = (long) luaL_checkinteger(L, 2);
814 listitem_T *li; 815 listitem_T *li;
815 if (l->lv_lock) 816 if (l->lv_lock)
832 } 833 }
833 return 0; 834 return 0;
834 } 835 }
835 836
836 static int 837 static int
837 luaV_list_add (lua_State *L) 838 luaV_list_add(lua_State *L)
838 { 839 {
839 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 840 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
840 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 841 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
841 typval_T v; 842 typval_T v;
842 if (l->lv_lock) 843 if (l->lv_lock)
849 lua_settop(L, 1); 850 lua_settop(L, 1);
850 return 1; 851 return 1;
851 } 852 }
852 853
853 static int 854 static int
854 luaV_list_insert (lua_State *L) 855 luaV_list_insert(lua_State *L)
855 { 856 {
856 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 857 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
857 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 858 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
858 long pos = (long) luaL_optinteger(L, 3, 0); 859 long pos = (long) luaL_optinteger(L, 3, 0);
859 listitem_T *li = NULL; 860 listitem_T *li = NULL;
888 889
889 890
890 /* ======= Dict type ======= */ 891 /* ======= Dict type ======= */
891 892
892 static luaV_Dict * 893 static luaV_Dict *
893 luaV_newdict (lua_State *L, dict_T *dic) 894 luaV_newdict(lua_State *L, dict_T *dic)
894 { 895 {
895 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict)); 896 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
896 *d = dic; 897 *d = dic;
897 dic->dv_refcount++; /* reference in Lua */ 898 dic->dv_refcount++; /* reference in Lua */
898 luaV_setudata(L, dic); /* cache[dic] = udata */ 899 luaV_setudata(L, dic); /* cache[dic] = udata */
903 904
904 luaV_pushtype(dict_T, dict, luaV_Dict) 905 luaV_pushtype(dict_T, dict, luaV_Dict)
905 luaV_type_tostring(dict, LUAVIM_DICT) 906 luaV_type_tostring(dict, LUAVIM_DICT)
906 907
907 static int 908 static int
908 luaV_dict_len (lua_State *L) 909 luaV_dict_len(lua_State *L)
909 { 910 {
910 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 911 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
911 lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used); 912 lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used);
912 return 1; 913 return 1;
913 } 914 }
914 915
915 static int 916 static int
916 luaV_dict_iter (lua_State *L UNUSED) 917 luaV_dict_iter(lua_State *L UNUSED)
917 { 918 {
918 #ifdef FEAT_EVAL 919 #ifdef FEAT_EVAL
919 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 920 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
920 int n = lua_tointeger(L, lua_upvalueindex(3)); 921 int n = lua_tointeger(L, lua_upvalueindex(3));
921 dictitem_T *di; 922 dictitem_T *di;
933 return 0; 934 return 0;
934 #endif 935 #endif
935 } 936 }
936 937
937 static int 938 static int
938 luaV_dict_call (lua_State *L) 939 luaV_dict_call(lua_State *L)
939 { 940 {
940 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 941 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
941 hashtab_T *ht = &d->dv_hashtab; 942 hashtab_T *ht = &d->dv_hashtab;
942 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */ 943 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
943 lua_pushlightuserdata(L, (void *) ht->ht_array); 944 lua_pushlightuserdata(L, (void *) ht->ht_array);
1035 { 1036 {
1036 luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref)); 1037 luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref));
1037 1038
1038 if (name != NULL) 1039 if (name != NULL)
1039 { 1040 {
1040 func_ref(name); /* as in copy_tv */ 1041 func_ref(name);
1041 f->tv.vval.v_string = vim_strsave(name); 1042 f->name = vim_strsave(name);
1042 } 1043 }
1043 f->tv.v_type = VAR_FUNC;
1044 f->args.v_type = VAR_LIST;
1045 f->self = NULL; 1044 f->self = NULL;
1046 luaV_getfield(L, LUAVIM_FUNCREF); 1045 luaV_getfield(L, LUAVIM_FUNCREF);
1047 lua_setmetatable(L, -2); 1046 lua_setmetatable(L, -2);
1048 return f; 1047 return f;
1049 } 1048 }
1050 1049
1051 static luaV_Funcref * 1050 static luaV_Funcref *
1052 luaV_pushfuncref(lua_State *L, typval_T *tv) 1051 luaV_pushfuncref(lua_State *L, char_u *name)
1053 { 1052 {
1054 luaV_Funcref *f = luaV_newfuncref(L, NULL); 1053 return luaV_newfuncref(L, name);
1055 copy_tv(tv, &f->tv);
1056 clear_tv(tv);
1057 return f;
1058 } 1054 }
1059 1055
1060 1056
1061 luaV_type_tostring(funcref, LUAVIM_FUNCREF) 1057 luaV_type_tostring(funcref, LUAVIM_FUNCREF)
1062 1058
1063 static int 1059 static int
1064 luaV_funcref_gc(lua_State *L) 1060 luaV_funcref_gc(lua_State *L)
1065 { 1061 {
1066 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1062 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1067 1063
1068 func_unref(f->tv.vval.v_string); 1064 func_unref(f->name);
1069 vim_free(f->tv.vval.v_string); 1065 vim_free(f->name);
1070 dict_unref(f->self); 1066 // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self"
1067 // will be (or has been already) freed by Vim's garbage collection.
1071 return 0; 1068 return 0;
1072 } 1069 }
1073 1070
1074 /* equivalent to string(funcref) */ 1071 /* equivalent to string(funcref) */
1075 static int 1072 static int
1076 luaV_funcref_len(lua_State *L) 1073 luaV_funcref_len(lua_State *L)
1077 { 1074 {
1078 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1075 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1079 1076
1080 lua_pushstring(L, (const char *) f->tv.vval.v_string); 1077 lua_pushstring(L, (const char *) f->name);
1081 return 1; 1078 return 1;
1082 } 1079 }
1083 1080
1084 static int 1081 static int
1085 luaV_funcref_call(lua_State *L) 1082 luaV_funcref_call(lua_State *L)
1086 { 1083 {
1087 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1084 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1088 int i, n = lua_gettop(L) - 1; /* #args */ 1085 int i, n = lua_gettop(L) - 1; // #args
1089 int status; 1086 int status = FAIL;
1090 typval_T v, rettv; 1087 typval_T args;
1091 1088 typval_T rettv;
1092 f->args.vval.v_list = list_alloc(); 1089
1093 rettv.v_type = VAR_UNKNOWN; /* as in clear_tv */ 1090 args.v_type = VAR_LIST;
1094 if (f->args.vval.v_list == NULL) 1091 args.vval.v_list = list_alloc();
1095 status = FAIL; 1092 rettv.v_type = VAR_UNKNOWN; // as in clear_tv
1096 else 1093 if (args.vval.v_list != NULL)
1097 { 1094 {
1095 typval_T v;
1096
1098 for (i = 0; i < n; i++) 1097 for (i = 0; i < n; i++)
1099 { 1098 {
1100 luaV_checktypval(L, i + 2, &v, "calling funcref"); 1099 luaV_checktypval(L, i + 2, &v, "calling funcref");
1101 list_append_tv(f->args.vval.v_list, &v); 1100 list_append_tv(args.vval.v_list, &v);
1102 clear_tv(&v); 1101 clear_tv(&v);
1103 } 1102 }
1104 status = func_call(f->tv.vval.v_string, &f->args, 1103 status = func_call(f->name, &args, NULL, f->self, &rettv);
1105 NULL, f->self, &rettv);
1106 if (status == OK) 1104 if (status == OK)
1107 luaV_pushtypval(L, &rettv); 1105 luaV_pushtypval(L, &rettv);
1108 clear_tv(&f->args); 1106 clear_tv(&args);
1109 clear_tv(&rettv); 1107 clear_tv(&rettv);
1110 } 1108 }
1111 if (status != OK) 1109 if (status != OK)
1112 luaL_error(L, "cannot call funcref"); 1110 luaL_error(L, "cannot call funcref");
1113 return 1; 1111 return 1;
1366 lua_pushnil(L); 1364 lua_pushnil(L);
1367 return 1; 1365 return 1;
1368 } 1366 }
1369 1367
1370 static int 1368 static int
1371 luaV_window_newindex (lua_State *L) 1369 luaV_window_newindex(lua_State *L)
1372 { 1370 {
1373 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1371 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1374 const char *s = luaL_checkstring(L, 2); 1372 const char *s = luaL_checkstring(L, 2);
1375 int v = luaL_checkinteger(L, 3); 1373 int v = luaL_checkinteger(L, 3);
1376 if (strncmp(s, "line", 4) == 0) 1374 if (strncmp(s, "line", 4) == 0)
1766 luaV_setudata(L, lua_touserdata(L, 1)); 1764 luaV_setudata(L, lua_touserdata(L, 1));
1767 return 0; 1765 return 0;
1768 } 1766 }
1769 1767
1770 static int 1768 static int
1771 luaV_luaeval (lua_State *L) 1769 luaV_luaeval(lua_State *L)
1772 { 1770 {
1773 luaL_Buffer b; 1771 luaL_Buffer b;
1774 size_t l; 1772 size_t l;
1775 const char *str = lua_tolstring(L, 1, &l); 1773 const char *str = lua_tolstring(L, 1, &l);
1776 typval_T *arg = (typval_T *) lua_touserdata(L, 2); 1774 typval_T *arg = (typval_T *) lua_touserdata(L, 2);
1795 emsg("luaeval: cannot convert value"); 1793 emsg("luaeval: cannot convert value");
1796 return 0; 1794 return 0;
1797 } 1795 }
1798 1796
1799 static int 1797 static int
1800 luaV_setref (lua_State *L) 1798 luaV_setref(lua_State *L)
1801 { 1799 {
1802 int copyID = lua_tointeger(L, 1); 1800 int copyID = lua_tointeger(L, 1);
1803 int abort = FALSE; 1801 int abort = FALSE;
1804 typval_T tv;
1805 1802
1806 luaV_getfield(L, LUAVIM_LIST); 1803 luaV_getfield(L, LUAVIM_LIST);
1807 luaV_getfield(L, LUAVIM_DICT); 1804 luaV_getfield(L, LUAVIM_DICT);
1805 luaV_getfield(L, LUAVIM_FUNCREF);
1808 lua_pushnil(L); 1806 lua_pushnil(L);
1809 /* traverse cache table */ 1807 // traverse cache table
1810 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) 1808 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0)
1811 { 1809 {
1812 lua_getmetatable(L, -1); 1810 lua_getmetatable(L, -1);
1813 if (lua_rawequal(L, -1, 2)) /* list? */ 1811 if (lua_rawequal(L, -1, 2)) // list?
1814 { 1812 {
1815 tv.v_type = VAR_LIST; 1813 list_T *l = (list_T *)lua_touserdata(L, 5); // key
1816 tv.vval.v_list = (list_T *) lua_touserdata(L, 4); /* key */ 1814
1817 abort = set_ref_in_item(&tv, copyID, NULL, NULL); 1815 if (l->lv_copyID != copyID)
1818 } 1816 {
1819 else if (lua_rawequal(L, -1, 3)) /* dict? */ 1817 l->lv_copyID = copyID;
1820 { 1818 abort = set_ref_in_list(l, copyID, NULL);
1821 tv.v_type = VAR_DICT; 1819 }
1822 tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */ 1820 }
1823 abort = set_ref_in_item(&tv, copyID, NULL, NULL); 1821 else if (lua_rawequal(L, -1, 3)) // dict?
1824 } 1822 {
1825 lua_pop(L, 2); /* metatable and value */ 1823 dict_T *d = (dict_T *)lua_touserdata(L, 5); // key
1824
1825 if (d->dv_copyID != copyID)
1826 {
1827 d->dv_copyID = copyID;
1828 abort = set_ref_in_ht(&d->dv_hashtab, copyID, NULL);
1829 }
1830 }
1831 else if (lua_rawequal(L, -1, 4)) // funcref?
1832 {
1833 luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key
1834
1835 if (f->self != NULL && f->self->dv_copyID != copyID)
1836 {
1837 f->self->dv_copyID = copyID;
1838 abort = set_ref_in_ht(&f->self->dv_hashtab, copyID, NULL);
1839 }
1840 }
1841 lua_pop(L, 2); // metatable and value
1826 } 1842 }
1827 lua_pushinteger(L, abort); 1843 lua_pushinteger(L, abort);
1828 return 1; 1844 return 1;
1829 } 1845 }
1830 1846
2051 2067
2052 luaV_freetype(buf_T, buffer) 2068 luaV_freetype(buf_T, buffer)
2053 luaV_freetype(win_T, window) 2069 luaV_freetype(win_T, window)
2054 2070
2055 void 2071 void
2056 do_luaeval (char_u *str, typval_T *arg, typval_T *rettv) 2072 do_luaeval(char_u *str, typval_T *arg, typval_T *rettv)
2057 { 2073 {
2058 lua_init(); 2074 lua_init();
2059 luaV_getfield(L, LUAVIM_LUAEVAL); 2075 luaV_getfield(L, LUAVIM_LUAEVAL);
2060 lua_pushstring(L, (char *) str); 2076 lua_pushstring(L, (char *) str);
2061 lua_pushlightuserdata(L, (void *) arg); 2077 lua_pushlightuserdata(L, (void *) arg);
2062 lua_pushlightuserdata(L, (void *) rettv); 2078 lua_pushlightuserdata(L, (void *) rettv);
2063 lua_call(L, 3, 0); 2079 lua_call(L, 3, 0);
2064 } 2080 }
2065 2081
2066 int 2082 int
2067 set_ref_in_lua (int copyID) 2083 set_ref_in_lua(int copyID)
2068 { 2084 {
2069 int aborted = 0; 2085 int aborted = 0;
2070 2086
2071 if (lua_isopen()) 2087 if (lua_isopen())
2072 { 2088 {