xref: /vim-8.2.3635/src/if_lua.c (revision dad4473f)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Lua interface by Luis Carvalho
6  *
7  * Do ":help uganda"  in Vim to read copying and usage conditions.
8  * Do ":help credits" in Vim to see a list of people who contributed.
9  * See README.txt for an overview of the Vim source code.
10  */
11 
12 #include "vim.h"
13 
14 #include <lua.h>
15 #include <lualib.h>
16 #include <lauxlib.h>
17 
18 // Only do the following when the feature is enabled.  Needed for "make
19 // depend".
20 #if defined(FEAT_LUA) || defined(PROTO)
21 
22 #define LUAVIM_CHUNKNAME "vim chunk"
23 #define LUAVIM_NAME "vim"
24 #define LUAVIM_EVALNAME "luaeval"
25 #define LUAVIM_EVALHEADER "local _A=select(1,...) return "
26 
27 typedef buf_T *luaV_Buffer;
28 typedef win_T *luaV_Window;
29 typedef dict_T *luaV_Dict;
30 typedef list_T *luaV_List;
31 typedef blob_T *luaV_Blob;
32 typedef struct {
33     char_u	*name;	// funcref
34     dict_T	*self;	// selfdict
35 } luaV_Funcref;
36 typedef int (*msgfunc_T)(char *);
37 
38 typedef struct {
39     int lua_funcref;    // ref to a lua func
40     int lua_tableref;   // ref to a lua table if metatable else LUA_NOREF. used
41 			// for __call
42     lua_State *L;
43 } luaV_CFuncState;
44 
45 static const char LUAVIM_DICT[] = "dict";
46 static const char LUAVIM_LIST[] = "list";
47 static const char LUAVIM_BLOB[] = "blob";
48 static const char LUAVIM_FUNCREF[] = "funcref";
49 static const char LUAVIM_BUFFER[] = "buffer";
50 static const char LUAVIM_WINDOW[] = "window";
51 static const char LUAVIM_FREE[] = "luaV_free";
52 static const char LUAVIM_LUAEVAL[] = "luaV_luaeval";
53 static const char LUAVIM_SETREF[] = "luaV_setref";
54 
55 static const char LUA___CALL[] = "__call";
56 
57 // most functions are closures with a cache table as first upvalue;
58 // get/setudata manage references to vim userdata in cache table through
59 // object pointers (light userdata)
60 #define luaV_getudata(L, v) \
61     lua_pushlightuserdata((L), (void *) (v)); \
62     lua_rawget((L), lua_upvalueindex(1))
63 #define luaV_setudata(L, v) \
64     lua_pushlightuserdata((L), (void *) (v)); \
65     lua_pushvalue((L), -2); \
66     lua_rawset((L), lua_upvalueindex(1))
67 #define luaV_getfield(L, s) \
68     lua_pushlightuserdata((L), (void *)(s)); \
69     lua_rawget((L), LUA_REGISTRYINDEX)
70 #define luaV_checksandbox(L) \
71     if (sandbox) luaL_error((L), "not allowed in sandbox")
72 #define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
73 #define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
74 #define luaV_checktypval(L, a, v, msg) \
75     do { \
76 	if (luaV_totypval(L, a, v) == FAIL) \
77 	    luaL_error(L, msg ": cannot convert value"); \
78     } while (0)
79 
80 static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
81 static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
82 static luaV_Blob *luaV_pushblob(lua_State *L, blob_T *blo);
83 static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
84 static int luaV_call_lua_func(int argcount, typval_T *argvars, typval_T *rettv, void *state);
85 static void luaV_call_lua_func_free(void *state);
86 
87 #if LUA_VERSION_NUM <= 501
88 #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
89 #define luaL_typeerror luaL_typerror
90 #else
91 #define luaV_openlib luaL_setfuncs
92 #endif
93 
94 #ifdef DYNAMIC_LUA
95 
96 #ifndef MSWIN
97 # include <dlfcn.h>
98 # define HANDLE void*
99 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
100 # define symbol_from_dll dlsym
101 # define close_dll dlclose
102 #else
103 # define load_dll vimLoadLib
104 # define symbol_from_dll GetProcAddress
105 # define close_dll FreeLibrary
106 #endif
107 
108 // lauxlib
109 #if LUA_VERSION_NUM <= 501
110 #define luaL_register dll_luaL_register
111 #define luaL_prepbuffer dll_luaL_prepbuffer
112 #define luaL_openlib dll_luaL_openlib
113 #define luaL_typerror dll_luaL_typerror
114 #define luaL_loadfile dll_luaL_loadfile
115 #define luaL_loadbuffer dll_luaL_loadbuffer
116 #else
117 #define luaL_prepbuffsize dll_luaL_prepbuffsize
118 #define luaL_setfuncs dll_luaL_setfuncs
119 #define luaL_loadfilex dll_luaL_loadfilex
120 #define luaL_loadbufferx dll_luaL_loadbufferx
121 #define luaL_argerror dll_luaL_argerror
122 #endif
123 #if LUA_VERSION_NUM >= 504
124 #define luaL_typeerror dll_luaL_typeerror
125 #endif
126 #define luaL_checkany dll_luaL_checkany
127 #define luaL_checklstring dll_luaL_checklstring
128 #define luaL_checkinteger dll_luaL_checkinteger
129 #define luaL_optinteger dll_luaL_optinteger
130 #define luaL_checktype dll_luaL_checktype
131 #define luaL_error dll_luaL_error
132 #define luaL_newstate dll_luaL_newstate
133 #define luaL_buffinit dll_luaL_buffinit
134 #define luaL_addlstring dll_luaL_addlstring
135 #define luaL_pushresult dll_luaL_pushresult
136 #define luaL_loadstring dll_luaL_loadstring
137 #define luaL_ref dll_luaL_ref
138 #define luaL_unref dll_luaL_unref
139 // lua
140 #if LUA_VERSION_NUM <= 501
141 #define lua_tonumber dll_lua_tonumber
142 #define lua_tointeger dll_lua_tointeger
143 #define lua_call dll_lua_call
144 #define lua_pcall dll_lua_pcall
145 #else
146 #define lua_tonumberx dll_lua_tonumberx
147 #define lua_tointegerx dll_lua_tointegerx
148 #define lua_callk dll_lua_callk
149 #define lua_pcallk dll_lua_pcallk
150 #define lua_getglobal dll_lua_getglobal
151 #define lua_setglobal dll_lua_setglobal
152 #endif
153 #if LUA_VERSION_NUM <= 502
154 #define lua_replace dll_lua_replace
155 #define lua_remove dll_lua_remove
156 #endif
157 #if LUA_VERSION_NUM >= 503
158 #define lua_rotate dll_lua_rotate
159 #define lua_copy dll_lua_copy
160 #endif
161 #define lua_typename dll_lua_typename
162 #define lua_close dll_lua_close
163 #define lua_gettop dll_lua_gettop
164 #define lua_settop dll_lua_settop
165 #define lua_pushvalue dll_lua_pushvalue
166 #define lua_isnumber dll_lua_isnumber
167 #define lua_isstring dll_lua_isstring
168 #define lua_type dll_lua_type
169 #define lua_rawequal dll_lua_rawequal
170 #define lua_toboolean dll_lua_toboolean
171 #define lua_tolstring dll_lua_tolstring
172 #define lua_touserdata dll_lua_touserdata
173 #define lua_pushnil dll_lua_pushnil
174 #define lua_pushnumber dll_lua_pushnumber
175 #define lua_pushinteger dll_lua_pushinteger
176 #define lua_pushlstring dll_lua_pushlstring
177 #define lua_pushstring dll_lua_pushstring
178 #define lua_pushfstring dll_lua_pushfstring
179 #define lua_pushcclosure dll_lua_pushcclosure
180 #define lua_pushboolean dll_lua_pushboolean
181 #define lua_pushlightuserdata dll_lua_pushlightuserdata
182 #define lua_getfield dll_lua_getfield
183 #define lua_rawget dll_lua_rawget
184 #define lua_rawgeti dll_lua_rawgeti
185 #define lua_createtable dll_lua_createtable
186 #if LUA_VERSION_NUM >= 504
187  #define lua_newuserdatauv dll_lua_newuserdatauv
188 #else
189  #define lua_newuserdata dll_lua_newuserdata
190 #endif
191 #define lua_getmetatable dll_lua_getmetatable
192 #define lua_setfield dll_lua_setfield
193 #define lua_rawset dll_lua_rawset
194 #define lua_rawseti dll_lua_rawseti
195 #define lua_setmetatable dll_lua_setmetatable
196 #define lua_next dll_lua_next
197 // libs
198 #define luaopen_base dll_luaopen_base
199 #define luaopen_table dll_luaopen_table
200 #define luaopen_string dll_luaopen_string
201 #define luaopen_math dll_luaopen_math
202 #define luaopen_io dll_luaopen_io
203 #define luaopen_os dll_luaopen_os
204 #define luaopen_package dll_luaopen_package
205 #define luaopen_debug dll_luaopen_debug
206 #define luaL_openlibs dll_luaL_openlibs
207 
208 // lauxlib
209 #if LUA_VERSION_NUM <= 501
210 void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
211 char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
212 void (*dll_luaL_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
213 int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
214 int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
215 int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
216 #else
217 char *(*dll_luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
218 void (*dll_luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
219 int (*dll_luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
220 int (*dll_luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
221 int (*dll_luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
222 #endif
223 #if LUA_VERSION_NUM >= 504
224 int (*dll_luaL_typeerror) (lua_State *L, int narg, const char *tname);
225 #endif
226 void (*dll_luaL_checkany) (lua_State *L, int narg);
227 const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
228 lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
229 lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
230 void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
231 int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
232 lua_State *(*dll_luaL_newstate) (void);
233 void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
234 void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
235 void (*dll_luaL_pushresult) (luaL_Buffer *B);
236 int (*dll_luaL_loadstring) (lua_State *L, const char *s);
237 int (*dll_luaL_ref) (lua_State *L, int idx);
238 #if LUA_VERSION_NUM <= 502
239 void (*dll_luaL_unref) (lua_State *L, int idx, int n);
240 #else
241 void (*dll_luaL_unref) (lua_State *L, int idx, lua_Integer n);
242 #endif
243 // lua
244 #if LUA_VERSION_NUM <= 501
245 lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
246 lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
247 void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
248 int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
249 #else
250 lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
251 lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
252 void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
253 	lua_CFunction k);
254 int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
255 	int ctx, lua_CFunction k);
256 void (*dll_lua_getglobal) (lua_State *L, const char *var);
257 void (*dll_lua_setglobal) (lua_State *L, const char *var);
258 #endif
259 #if LUA_VERSION_NUM <= 502
260 void (*dll_lua_replace) (lua_State *L, int idx);
261 void (*dll_lua_remove) (lua_State *L, int idx);
262 #endif
263 #if LUA_VERSION_NUM >= 503
264 void  (*dll_lua_rotate) (lua_State *L, int idx, int n);
265 void (*dll_lua_copy) (lua_State *L, int fromidx, int toidx);
266 #endif
267 const char *(*dll_lua_typename) (lua_State *L, int tp);
268 void       (*dll_lua_close) (lua_State *L);
269 int (*dll_lua_gettop) (lua_State *L);
270 void (*dll_lua_settop) (lua_State *L, int idx);
271 void (*dll_lua_pushvalue) (lua_State *L, int idx);
272 int (*dll_lua_isnumber) (lua_State *L, int idx);
273 int (*dll_lua_isstring) (lua_State *L, int idx);
274 int (*dll_lua_type) (lua_State *L, int idx);
275 int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
276 int (*dll_lua_toboolean) (lua_State *L, int idx);
277 const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
278 void *(*dll_lua_touserdata) (lua_State *L, int idx);
279 void (*dll_lua_pushnil) (lua_State *L);
280 void (*dll_lua_pushnumber) (lua_State *L, lua_Number n);
281 void (*dll_lua_pushinteger) (lua_State *L, lua_Integer n);
282 void (*dll_lua_pushlstring) (lua_State *L, const char *s, size_t l);
283 void (*dll_lua_pushstring) (lua_State *L, const char *s);
284 const char *(*dll_lua_pushfstring) (lua_State *L, const char *fmt, ...);
285 void (*dll_lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
286 void (*dll_lua_pushboolean) (lua_State *L, int b);
287 void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
288 void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
289 #if LUA_VERSION_NUM <= 502
290 void (*dll_lua_rawget) (lua_State *L, int idx);
291 void (*dll_lua_rawgeti) (lua_State *L, int idx, int n);
292 #else
293 int (*dll_lua_rawget) (lua_State *L, int idx);
294 int (*dll_lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
295 #endif
296 void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
297 #if LUA_VERSION_NUM >= 504
298 void *(*dll_lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue);
299 #else
300 void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
301 #endif
302 int (*dll_lua_getmetatable) (lua_State *L, int objindex);
303 void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
304 void (*dll_lua_rawset) (lua_State *L, int idx);
305 #if LUA_VERSION_NUM <= 502
306 void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
307 #else
308 void (*dll_lua_rawseti) (lua_State *L, int idx, lua_Integer n);
309 #endif
310 int (*dll_lua_setmetatable) (lua_State *L, int objindex);
311 int (*dll_lua_next) (lua_State *L, int idx);
312 // libs
313 int (*dll_luaopen_base) (lua_State *L);
314 int (*dll_luaopen_table) (lua_State *L);
315 int (*dll_luaopen_string) (lua_State *L);
316 int (*dll_luaopen_math) (lua_State *L);
317 int (*dll_luaopen_io) (lua_State *L);
318 int (*dll_luaopen_os) (lua_State *L);
319 int (*dll_luaopen_package) (lua_State *L);
320 int (*dll_luaopen_debug) (lua_State *L);
321 void (*dll_luaL_openlibs) (lua_State *L);
322 
323 typedef void **luaV_function;
324 typedef struct {
325     const char *name;
326     luaV_function func;
327 } luaV_Reg;
328 
329 static const luaV_Reg luaV_dll[] = {
330     // lauxlib
331 #if LUA_VERSION_NUM <= 501
332     {"luaL_register", (luaV_function) &dll_luaL_register},
333     {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
334     {"luaL_openlib", (luaV_function) &dll_luaL_openlib},
335     {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
336     {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
337     {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
338 #else
339     {"luaL_prepbuffsize", (luaV_function) &dll_luaL_prepbuffsize},
340     {"luaL_setfuncs", (luaV_function) &dll_luaL_setfuncs},
341     {"luaL_loadfilex", (luaV_function) &dll_luaL_loadfilex},
342     {"luaL_loadbufferx", (luaV_function) &dll_luaL_loadbufferx},
343     {"luaL_argerror", (luaV_function) &dll_luaL_argerror},
344 #endif
345 #if LUA_VERSION_NUM >= 504
346     {"luaL_typeerror", (luaV_function) &dll_luaL_typeerror},
347 #endif
348     {"luaL_checkany", (luaV_function) &dll_luaL_checkany},
349     {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
350     {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
351     {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
352     {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
353     {"luaL_error", (luaV_function) &dll_luaL_error},
354     {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
355     {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
356     {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
357     {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
358     {"luaL_loadstring", (luaV_function) &dll_luaL_loadstring},
359     {"luaL_ref", (luaV_function) &dll_luaL_ref},
360     {"luaL_unref", (luaV_function) &dll_luaL_unref},
361     // lua
362 #if LUA_VERSION_NUM <= 501
363     {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
364     {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
365     {"lua_call", (luaV_function) &dll_lua_call},
366     {"lua_pcall", (luaV_function) &dll_lua_pcall},
367 #else
368     {"lua_tonumberx", (luaV_function) &dll_lua_tonumberx},
369     {"lua_tointegerx", (luaV_function) &dll_lua_tointegerx},
370     {"lua_callk", (luaV_function) &dll_lua_callk},
371     {"lua_pcallk", (luaV_function) &dll_lua_pcallk},
372     {"lua_getglobal", (luaV_function) &dll_lua_getglobal},
373     {"lua_setglobal", (luaV_function) &dll_lua_setglobal},
374 #endif
375 #if LUA_VERSION_NUM <= 502
376     {"lua_replace", (luaV_function) &dll_lua_replace},
377     {"lua_remove", (luaV_function) &dll_lua_remove},
378 #endif
379 #if LUA_VERSION_NUM >= 503
380     {"lua_rotate", (luaV_function) &dll_lua_rotate},
381     {"lua_copy", (luaV_function) &dll_lua_copy},
382 #endif
383     {"lua_typename", (luaV_function) &dll_lua_typename},
384     {"lua_close", (luaV_function) &dll_lua_close},
385     {"lua_gettop", (luaV_function) &dll_lua_gettop},
386     {"lua_settop", (luaV_function) &dll_lua_settop},
387     {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
388     {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
389     {"lua_isstring", (luaV_function) &dll_lua_isstring},
390     {"lua_type", (luaV_function) &dll_lua_type},
391     {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
392     {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
393     {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
394     {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
395     {"lua_pushnil", (luaV_function) &dll_lua_pushnil},
396     {"lua_pushnumber", (luaV_function) &dll_lua_pushnumber},
397     {"lua_pushinteger", (luaV_function) &dll_lua_pushinteger},
398     {"lua_pushlstring", (luaV_function) &dll_lua_pushlstring},
399     {"lua_pushstring", (luaV_function) &dll_lua_pushstring},
400     {"lua_pushfstring", (luaV_function) &dll_lua_pushfstring},
401     {"lua_pushcclosure", (luaV_function) &dll_lua_pushcclosure},
402     {"lua_pushboolean", (luaV_function) &dll_lua_pushboolean},
403     {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
404     {"lua_getfield", (luaV_function) &dll_lua_getfield},
405     {"lua_rawget", (luaV_function) &dll_lua_rawget},
406     {"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
407     {"lua_createtable", (luaV_function) &dll_lua_createtable},
408 #if LUA_VERSION_NUM >= 504
409     {"lua_newuserdatauv", (luaV_function) &dll_lua_newuserdatauv},
410 #else
411     {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
412 #endif
413     {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
414     {"lua_setfield", (luaV_function) &dll_lua_setfield},
415     {"lua_rawset", (luaV_function) &dll_lua_rawset},
416     {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
417     {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
418     {"lua_next", (luaV_function) &dll_lua_next},
419     // libs
420     {"luaopen_base", (luaV_function) &dll_luaopen_base},
421     {"luaopen_table", (luaV_function) &dll_luaopen_table},
422     {"luaopen_string", (luaV_function) &dll_luaopen_string},
423     {"luaopen_math", (luaV_function) &dll_luaopen_math},
424     {"luaopen_io", (luaV_function) &dll_luaopen_io},
425     {"luaopen_os", (luaV_function) &dll_luaopen_os},
426     {"luaopen_package", (luaV_function) &dll_luaopen_package},
427     {"luaopen_debug", (luaV_function) &dll_luaopen_debug},
428     {"luaL_openlibs", (luaV_function) &dll_luaL_openlibs},
429     {NULL, NULL}
430 };
431 
432 static HANDLE hinstLua = NULL;
433 
434     static int
435 lua_link_init(char *libname, int verbose)
436 {
437     const luaV_Reg *reg;
438     if (hinstLua) return OK;
439     hinstLua = load_dll(libname);
440     if (!hinstLua)
441     {
442 	if (verbose)
443 	    semsg(_(e_loadlib), libname);
444 	return FAIL;
445     }
446     for (reg = luaV_dll; reg->func; reg++)
447     {
448 	if ((*reg->func = symbol_from_dll(hinstLua, reg->name)) == NULL)
449 	{
450 	    close_dll(hinstLua);
451 	    hinstLua = 0;
452 	    if (verbose)
453 		semsg(_(e_loadfunc), reg->name);
454 	    return FAIL;
455 	}
456     }
457     return OK;
458 }
459 #endif // DYNAMIC_LUA
460 
461 #if defined(DYNAMIC_LUA) || defined(PROTO)
462     int
463 lua_enabled(int verbose)
464 {
465     return lua_link_init((char *)p_luadll, verbose) == OK;
466 }
467 #endif
468 
469 #if LUA_VERSION_NUM > 501 && LUA_VERSION_NUM < 504
470     static int
471 luaL_typeerror(lua_State *L, int narg, const char *tname)
472 {
473     const char *msg = lua_pushfstring(L, "%s expected, got %s",
474 	    tname, luaL_typename(L, narg));
475     return luaL_argerror(L, narg, msg);
476 }
477 #endif
478 
479 
480 // =======   Internal   =======
481 
482     static void
483 luaV_newmetatable(lua_State *L, const char *tname)
484 {
485     lua_newtable(L);
486     lua_pushlightuserdata(L, (void *) tname);
487     lua_pushvalue(L, -2);
488     lua_rawset(L, LUA_REGISTRYINDEX);
489 }
490 
491     static void *
492 luaV_toudata(lua_State *L, int ud, const char *tname)
493 {
494     void *p = lua_touserdata(L, ud);
495 
496     if (p != NULL) // value is userdata?
497     {
498 	if (lua_getmetatable(L, ud)) // does it have a metatable?
499 	{
500 	    luaV_getfield(L, tname); // get metatable
501 	    if (lua_rawequal(L, -1, -2)) // MTs match?
502 	    {
503 		lua_pop(L, 2); // MTs
504 		return p;
505 	    }
506 	}
507     }
508     return NULL;
509 }
510 
511     static void *
512 luaV_checkcache(lua_State *L, void *p)
513 {
514     luaV_getudata(L, p);
515     if (lua_isnil(L, -1)) luaL_error(L, "invalid object");
516     lua_pop(L, 1);
517     return p;
518 }
519 
520 #define luaV_unbox(L,luatyp,ud) (*((luatyp *) lua_touserdata((L),(ud))))
521 
522 #define luaV_checkvalid(L,luatyp,ud) \
523     luaV_checkcache((L), (void *) luaV_unbox((L),luatyp,(ud)))
524 
525     static void *
526 luaV_checkudata(lua_State *L, int ud, const char *tname)
527 {
528     void *p = luaV_toudata(L, ud, tname);
529     if (p == NULL) luaL_typeerror(L, ud, tname);
530     return p;
531 }
532 
533     static void
534 luaV_pushtypval(lua_State *L, typval_T *tv)
535 {
536     if (tv == NULL)
537     {
538 	lua_pushnil(L);
539 	return;
540     }
541     switch (tv->v_type)
542     {
543 	case VAR_STRING:
544 	    lua_pushstring(L, tv->vval.v_string == NULL
545 					    ? "" : (char *)tv->vval.v_string);
546 	    break;
547 	case VAR_NUMBER:
548 	    lua_pushinteger(L, (int) tv->vval.v_number);
549 	    break;
550 #ifdef FEAT_FLOAT
551 	case VAR_FLOAT:
552 	    lua_pushnumber(L, (lua_Number) tv->vval.v_float);
553 	    break;
554 #endif
555 	case VAR_LIST:
556 	    luaV_pushlist(L, tv->vval.v_list);
557 	    break;
558 	case VAR_DICT:
559 	    luaV_pushdict(L, tv->vval.v_dict);
560 	    break;
561 	case VAR_BOOL:
562 	case VAR_SPECIAL:
563 	    if (tv->vval.v_number <= VVAL_TRUE)
564 		lua_pushinteger(L, (int) tv->vval.v_number);
565 	    else
566 		lua_pushnil(L);
567 	    break;
568 	case VAR_FUNC:
569 	    luaV_pushfuncref(L, tv->vval.v_string);
570 	    break;
571 	case VAR_PARTIAL:
572 	    // TODO: handle partial arguments
573 	    luaV_pushfuncref(L, partial_name(tv->vval.v_partial));
574 	    break;
575 
576 	case VAR_BLOB:
577 	    luaV_pushblob(L, tv->vval.v_blob);
578 	    break;
579 	default:
580 	    lua_pushnil(L);
581     }
582 }
583 
584 /*
585  * Converts lua value at 'pos' to typval 'tv'.
586  * Returns OK or FAIL.
587  */
588     static int
589 luaV_totypval(lua_State *L, int pos, typval_T *tv)
590 {
591     int status = OK;
592 
593     tv->v_lock = 0;
594 
595     switch (lua_type(L, pos))
596     {
597 	case LUA_TBOOLEAN:
598 	    tv->v_type = VAR_BOOL;
599 	    tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
600 	    break;
601 	case LUA_TNIL:
602 	    tv->v_type = VAR_SPECIAL;
603 	    tv->vval.v_number = VVAL_NULL;
604 	    break;
605 	case LUA_TSTRING:
606 	    tv->v_type = VAR_STRING;
607 	    tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos));
608 	    break;
609 	case LUA_TNUMBER:
610 #ifdef FEAT_FLOAT
611 	{
612 	    const lua_Number n = lua_tonumber(L, pos);
613 
614 	    if (n > (lua_Number)INT64_MAX || n < (lua_Number)INT64_MIN
615 		    || ((lua_Number)((varnumber_T)n)) != n)
616 	    {
617 		tv->v_type = VAR_FLOAT;
618 		tv->vval.v_float = (float_T)n;
619 	    }
620 	    else
621 	    {
622 		tv->v_type = VAR_NUMBER;
623 		tv->vval.v_number = (varnumber_T)n;
624 	    }
625 	}
626 #else
627 	    tv->v_type = VAR_NUMBER;
628 	    tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos);
629 #endif
630 	    break;
631 	case LUA_TFUNCTION:
632 	{
633 	    char_u *name;
634 	    luaV_CFuncState *state;
635 
636 	    lua_pushvalue(L, pos);
637 	    state = ALLOC_CLEAR_ONE(luaV_CFuncState);
638 	    state->lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
639 	    state->L = L;
640 	    state->lua_tableref = LUA_NOREF;
641 	    name = register_cfunc(&luaV_call_lua_func,
642 					      &luaV_call_lua_func_free, state);
643 	    tv->v_type = VAR_FUNC;
644 	    tv->vval.v_string = vim_strsave(name);
645 	    break;
646 	}
647 	case LUA_TTABLE:
648 	{
649 	    int lua_tableref;
650 
651 	    lua_pushvalue(L, pos);
652 	    lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX);
653 	    if (lua_getmetatable(L, pos)) {
654 		lua_getfield(L, -1, LUA___CALL);
655 		if (lua_isfunction(L, -1)) {
656 		    char_u *name;
657 		    int lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
658 		    luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
659 
660 		    state->lua_funcref = lua_funcref;
661 		    state->L = L;
662 		    state->lua_tableref = lua_tableref;
663 		    name = register_cfunc(&luaV_call_lua_func,
664 					      &luaV_call_lua_func_free, state);
665 		    tv->v_type = VAR_FUNC;
666 		    tv->vval.v_string = vim_strsave(name);
667 		    break;
668 		}
669 	    }
670 	    tv->v_type = VAR_NUMBER;
671 	    tv->vval.v_number = 0;
672 	    status = FAIL;
673 	    break;
674 	}
675 	case LUA_TUSERDATA:
676 	{
677 	    void *p = lua_touserdata(L, pos);
678 
679 	    if (lua_getmetatable(L, pos)) // has metatable?
680 	    {
681 		// check list
682 		luaV_getfield(L, LUAVIM_LIST);
683 		if (lua_rawequal(L, -1, -2))
684 		{
685 		    tv->v_type = VAR_LIST;
686 		    tv->vval.v_list = *((luaV_List *) p);
687 		    ++tv->vval.v_list->lv_refcount;
688 		    lua_pop(L, 2); // MTs
689 		    break;
690 		}
691 		// check dict
692 		luaV_getfield(L, LUAVIM_DICT);
693 		if (lua_rawequal(L, -1, -3))
694 		{
695 		    tv->v_type = VAR_DICT;
696 		    tv->vval.v_dict = *((luaV_Dict *) p);
697 		    ++tv->vval.v_dict->dv_refcount;
698 		    lua_pop(L, 3); // MTs
699 		    break;
700 		}
701 		// check blob
702 		luaV_getfield(L, LUAVIM_BLOB);
703 		if (lua_rawequal(L, -1, -4))
704 		{
705 		    tv->v_type = VAR_BLOB;
706 		    tv->vval.v_blob = *((luaV_Blob *) p);
707 		    ++tv->vval.v_blob->bv_refcount;
708 		    lua_pop(L, 4); // MTs
709 		    break;
710 		}
711 		// check funcref
712 		luaV_getfield(L, LUAVIM_FUNCREF);
713 		if (lua_rawequal(L, -1, -5))
714 		{
715 		    luaV_Funcref *f = (luaV_Funcref *) p;
716 
717 		    func_ref(f->name);
718 		    tv->v_type = VAR_FUNC;
719 		    tv->vval.v_string = vim_strsave(f->name);
720 		    lua_pop(L, 5); // MTs
721 		    break;
722 		}
723 		lua_pop(L, 4); // MTs
724 	    }
725 	}
726 	// FALLTHROUGH
727 	default:
728 	    tv->v_type = VAR_NUMBER;
729 	    tv->vval.v_number = 0;
730 	    status = FAIL;
731     }
732     return status;
733 }
734 
735 /*
736  * similar to luaL_addlstring, but replaces \0 with \n if toline and
737  * \n with \0 otherwise
738  */
739     static void
740 luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline)
741 {
742     while (l--)
743     {
744 	if (*s == '\0' && toline)
745 	    luaL_addchar(b, '\n');
746 	else if (*s == '\n' && !toline)
747 	    luaL_addchar(b, '\0');
748 	else
749 	    luaL_addchar(b, *s);
750 	s++;
751     }
752 }
753 
754     static void
755 luaV_pushline(lua_State *L, buf_T *buf, linenr_T n)
756 {
757     const char *s = (const char *) ml_get_buf(buf, n, FALSE);
758     luaL_Buffer b;
759     luaL_buffinit(L, &b);
760     luaV_addlstring(&b, s, strlen(s), 0);
761     luaL_pushresult(&b);
762 }
763 
764     static char_u *
765 luaV_toline(lua_State *L, int pos)
766 {
767     size_t l;
768     const char *s = lua_tolstring(L, pos, &l);
769 
770     luaL_Buffer b;
771     luaL_buffinit(L, &b);
772     luaV_addlstring(&b, s, l, 1);
773     luaL_pushresult(&b);
774     return (char_u *) lua_tostring(L, -1);
775 }
776 
777 /*
778  * pops a string s from the top of the stack and calls mf(t) for pieces t of
779  * s separated by newlines
780  */
781     static void
782 luaV_msgfunc(lua_State *L, msgfunc_T mf)
783 {
784     luaL_Buffer b;
785     size_t l;
786     const char *p, *s = lua_tolstring(L, -1, &l);
787     luaL_buffinit(L, &b);
788     luaV_addlstring(&b, s, l, 0);
789     luaL_pushresult(&b);
790     // break string
791     p = s = lua_tolstring(L, -1, &l);
792     while (l--)
793     {
794 	if (*p++ == '\0') // break?
795 	{
796 	    mf((char *)s);
797 	    s = p;
798 	}
799     }
800     mf((char *)s);
801     lua_pop(L, 2); // original and modified strings
802 }
803 
804 #define luaV_newtype(typ,tname,luatyp,luatname) \
805 	static luatyp * \
806     luaV_new##tname(lua_State *L, typ *obj) \
807     { \
808 	luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
809 	*o = obj; \
810 	luaV_setudata(L, obj); /* cache[obj] = udata */ \
811 	luaV_getfield(L, luatname); \
812 	lua_setmetatable(L, -2); \
813 	return o; \
814     }
815 
816 #define luaV_pushtype(typ,tname,luatyp) \
817 	static luatyp * \
818     luaV_push##tname(lua_State *L, typ *obj) \
819     { \
820 	luatyp *o = NULL; \
821 	if (obj == NULL) \
822 	    lua_pushnil(L); \
823 	else { \
824 	    luaV_getudata(L, obj); \
825 	    if (lua_isnil(L, -1)) /* not interned? */ \
826 	    { \
827 		lua_pop(L, 1); \
828 		o = luaV_new##tname(L, obj); \
829 	    } \
830 	    else \
831 		o = (luatyp *) lua_touserdata(L, -1); \
832 	} \
833 	return o; \
834     }
835 
836 #define luaV_type_tostring(tname,luatname) \
837 	static int \
838     luaV_##tname##_tostring(lua_State *L) \
839     { \
840 	lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
841 	return 1; \
842     }
843 
844 // =======   List type   =======
845 
846     static luaV_List *
847 luaV_newlist(lua_State *L, list_T *lis)
848 {
849     luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
850     *l = lis;
851     lis->lv_refcount++; // reference in Lua
852     luaV_setudata(L, lis); // cache[lis] = udata
853     luaV_getfield(L, LUAVIM_LIST);
854     lua_setmetatable(L, -2);
855     return l;
856 }
857 
858 luaV_pushtype(list_T, list, luaV_List)
859 luaV_type_tostring(list, LUAVIM_LIST)
860 
861     static int
862 luaV_list_len(lua_State *L)
863 {
864     list_T *l = luaV_unbox(L, luaV_List, 1);
865     lua_pushinteger(L, (int) list_len(l));
866     return 1;
867 }
868 
869     static int
870 luaV_list_iter(lua_State *L)
871 {
872     listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
873     if (li == NULL) return 0;
874     luaV_pushtypval(L, &li->li_tv);
875     lua_pushlightuserdata(L, (void *) li->li_next);
876     lua_replace(L, lua_upvalueindex(2));
877     return 1;
878 }
879 
880     static int
881 luaV_list_call(lua_State *L)
882 {
883     list_T *l = luaV_unbox(L, luaV_List, 1);
884     lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along
885     lua_pushlightuserdata(L, (void *) l->lv_first);
886     lua_pushcclosure(L, luaV_list_iter, 2);
887     return 1;
888 }
889 
890     static int
891 luaV_list_index(lua_State *L)
892 {
893     list_T *l = luaV_unbox(L, luaV_List, 1);
894     if (lua_isnumber(L, 2)) // list item?
895     {
896 	long n = (long) luaL_checkinteger(L, 2);
897 	listitem_T *li;
898 
899 	// Lua array index starts with 1 while Vim uses 0, subtract 1 to
900 	// normalize.
901 	n -= 1;
902 	li = list_find(l, n);
903 	if (li == NULL)
904 	    lua_pushnil(L);
905 	else
906 	    luaV_pushtypval(L, &li->li_tv);
907     }
908     else if (lua_isstring(L, 2)) // method?
909     {
910 	const char *s = lua_tostring(L, 2);
911 	if (strncmp(s, "add", 3) == 0
912 		|| strncmp(s, "insert", 6) == 0)
913 	{
914 	    lua_getmetatable(L, 1);
915 	    lua_getfield(L, -1, s);
916 	}
917 	else
918 	    lua_pushnil(L);
919     }
920     else
921 	lua_pushnil(L);
922     return 1;
923 }
924 
925     static int
926 luaV_list_newindex(lua_State *L)
927 {
928     list_T *l = luaV_unbox(L, luaV_List, 1);
929     long n = (long) luaL_checkinteger(L, 2);
930     listitem_T *li;
931 
932     // Lua array index starts with 1 while Vim uses 0, subtract 1 to normalize.
933     n -= 1;
934 
935     if (l->lv_lock)
936 	luaL_error(L, "list is locked");
937     li = list_find(l, n);
938     if (li == NULL)
939     {
940         if (!lua_isnil(L, 3))
941         {
942 	   typval_T v;
943 	   luaV_checktypval(L, 3, &v, "inserting list item");
944 	   if (list_insert_tv(l, &v, li) == FAIL)
945 	        luaL_error(L, "failed to add item to list");
946 	   clear_tv(&v);
947         }
948     }
949     else
950     {
951         if (lua_isnil(L, 3)) // remove?
952         {
953 	    vimlist_remove(l, li, li);
954 	    listitem_free(l, li);
955         }
956         else
957         {
958 	    typval_T v;
959 	    luaV_checktypval(L, 3, &v, "setting list item");
960 	    clear_tv(&li->li_tv);
961 	    li->li_tv = v;
962         }
963     }
964     return 0;
965 }
966 
967     static int
968 luaV_list_add(lua_State *L)
969 {
970     luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
971     list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
972     typval_T v;
973     if (l->lv_lock)
974 	luaL_error(L, "list is locked");
975     lua_settop(L, 2);
976     luaV_checktypval(L, 2, &v, "adding list item");
977     if (list_append_tv(l, &v) == FAIL)
978 	luaL_error(L, "failed to add item to list");
979     clear_tv(&v);
980     lua_settop(L, 1);
981     return 1;
982 }
983 
984     static int
985 luaV_list_insert(lua_State *L)
986 {
987     luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
988     list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
989     long pos = (long) luaL_optinteger(L, 3, 0);
990     listitem_T *li = NULL;
991     typval_T v;
992     if (l->lv_lock)
993 	luaL_error(L, "list is locked");
994     if (pos < l->lv_len)
995     {
996 	li = list_find(l, pos);
997 	if (li == NULL)
998 	    luaL_error(L, "invalid position");
999     }
1000     lua_settop(L, 2);
1001     luaV_checktypval(L, 2, &v, "inserting list item");
1002     if (list_insert_tv(l, &v, li) == FAIL)
1003 	luaL_error(L, "failed to add item to list");
1004     clear_tv(&v);
1005     lua_settop(L, 1);
1006     return 1;
1007 }
1008 
1009 static const luaL_Reg luaV_List_mt[] = {
1010     {"__tostring", luaV_list_tostring},
1011     {"__len", luaV_list_len},
1012     {"__call", luaV_list_call},
1013     {"__index", luaV_list_index},
1014     {"__newindex", luaV_list_newindex},
1015     {"add", luaV_list_add},
1016     {"insert", luaV_list_insert},
1017     {NULL, NULL}
1018 };
1019 
1020 
1021 // =======   Dict type   =======
1022 
1023     static luaV_Dict *
1024 luaV_newdict(lua_State *L, dict_T *dic)
1025 {
1026     luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
1027     *d = dic;
1028     dic->dv_refcount++; // reference in Lua
1029     luaV_setudata(L, dic); // cache[dic] = udata
1030     luaV_getfield(L, LUAVIM_DICT);
1031     lua_setmetatable(L, -2);
1032     return d;
1033 }
1034 
1035 luaV_pushtype(dict_T, dict, luaV_Dict)
1036 luaV_type_tostring(dict, LUAVIM_DICT)
1037 
1038     static int
1039 luaV_dict_len(lua_State *L)
1040 {
1041     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1042     lua_pushinteger(L, (int) dict_len(d));
1043     return 1;
1044 }
1045 
1046     static int
1047 luaV_dict_iter(lua_State *L UNUSED)
1048 {
1049 #ifdef FEAT_EVAL
1050     hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
1051     int n = lua_tointeger(L, lua_upvalueindex(3));
1052     dictitem_T *di;
1053     if (n <= 0) return 0;
1054     while (HASHITEM_EMPTY(hi)) hi++;
1055     di = dict_lookup(hi);
1056     lua_pushstring(L, (char *) hi->hi_key);
1057     luaV_pushtypval(L, &di->di_tv);
1058     lua_pushlightuserdata(L, (void *) (hi + 1));
1059     lua_replace(L, lua_upvalueindex(2));
1060     lua_pushinteger(L, n - 1);
1061     lua_replace(L, lua_upvalueindex(3));
1062     return 2;
1063 #else
1064     return 0;
1065 #endif
1066 }
1067 
1068     static int
1069 luaV_dict_call(lua_State *L)
1070 {
1071     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1072     hashtab_T *ht = &d->dv_hashtab;
1073     lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along
1074     lua_pushlightuserdata(L, (void *) ht->ht_array);
1075     lua_pushinteger(L, ht->ht_used); // # remaining items
1076     lua_pushcclosure(L, luaV_dict_iter, 3);
1077     return 1;
1078 }
1079 
1080     static int
1081 luaV_dict_index(lua_State *L)
1082 {
1083     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1084     char_u *key = (char_u *) luaL_checkstring(L, 2);
1085     dictitem_T *di = dict_find(d, key, -1);
1086 
1087     if (di == NULL)
1088 	lua_pushnil(L);
1089     else
1090     {
1091 	luaV_pushtypval(L, &di->di_tv);
1092 	if (di->di_tv.v_type == VAR_FUNC) // funcref?
1093 	{
1094 	    luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1);
1095 	    f->self = d; // keep "self" reference
1096 	    d->dv_refcount++;
1097 	}
1098     }
1099     return 1;
1100 }
1101 
1102     static int
1103 luaV_dict_newindex(lua_State *L)
1104 {
1105     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1106     char_u *key = (char_u *) luaL_checkstring(L, 2);
1107     dictitem_T *di;
1108     typval_T tv;
1109 
1110     if (d->dv_lock)
1111 	luaL_error(L, "dict is locked");
1112     if (key == NULL)
1113 	return 0;
1114     if (*key == NUL)
1115 	luaL_error(L, "empty key");
1116     if (!lua_isnil(L, 3)) // read value?
1117     {
1118 	luaV_checktypval(L, 3, &tv, "setting dict item");
1119 	if (d->dv_scope == VAR_DEF_SCOPE && tv.v_type == VAR_FUNC)
1120 	{
1121 	    clear_tv(&tv);
1122 	    luaL_error(L, "cannot assign funcref to builtin scope");
1123 	}
1124     }
1125     di = dict_find(d, key, -1);
1126     if (di == NULL) // non-existing key?
1127     {
1128 	if (lua_isnil(L, 3))
1129 	    return 0;
1130 	di = dictitem_alloc(key);
1131 	if (di == NULL)
1132 	{
1133 	    clear_tv(&tv);
1134 	    return 0;
1135 	}
1136 	if (dict_add(d, di) == FAIL)
1137 	{
1138 	    vim_free(di);
1139 	    clear_tv(&tv);
1140 	    return 0;
1141 	}
1142     }
1143     else
1144 	clear_tv(&di->di_tv);
1145     if (lua_isnil(L, 3)) // remove?
1146     {
1147 	hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key);
1148 	hash_remove(&d->dv_hashtab, hi);
1149 	dictitem_free(di);
1150     }
1151     else
1152 	di->di_tv = tv;
1153     return 0;
1154 }
1155 
1156 static const luaL_Reg luaV_Dict_mt[] = {
1157     {"__tostring", luaV_dict_tostring},
1158     {"__len", luaV_dict_len},
1159     {"__call", luaV_dict_call},
1160     {"__index", luaV_dict_index},
1161     {"__newindex", luaV_dict_newindex},
1162     {NULL, NULL}
1163 };
1164 
1165 
1166 // =======   Blob type   =======
1167 
1168     static luaV_Blob *
1169 luaV_newblob(lua_State *L, blob_T *blo)
1170 {
1171     luaV_Blob *b = (luaV_Blob *) lua_newuserdata(L, sizeof(luaV_Blob));
1172     *b = blo;
1173     blo->bv_refcount++; // reference in Lua
1174     luaV_setudata(L, blo); // cache[blo] = udata
1175     luaV_getfield(L, LUAVIM_BLOB);
1176     lua_setmetatable(L, -2);
1177     return b;
1178 }
1179 
1180 luaV_pushtype(blob_T, blob, luaV_Blob)
1181 luaV_type_tostring(blob, LUAVIM_BLOB)
1182 
1183     static int
1184 luaV_blob_gc(lua_State *L)
1185 {
1186     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1187     blob_unref(b);
1188     return 0;
1189 }
1190 
1191     static int
1192 luaV_blob_len(lua_State *L)
1193 {
1194     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1195     lua_pushinteger(L, (int) blob_len(b));
1196     return 1;
1197 }
1198 
1199     static int
1200 luaV_blob_index(lua_State *L)
1201 {
1202     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1203     if (lua_isnumber(L, 2))
1204     {
1205 	int idx = luaL_checkinteger(L, 2);
1206 	if (idx < blob_len(b))
1207 	    lua_pushnumber(L, (lua_Number) blob_get(b, idx));
1208 	else
1209 	    lua_pushnil(L);
1210     }
1211     else if (lua_isstring(L, 2))
1212     {
1213 	const char *s = lua_tostring(L, 2);
1214 	if (strncmp(s, "add", 3) == 0)
1215 	{
1216 	    lua_getmetatable(L, 1);
1217 	    lua_getfield(L, -1, s);
1218 	}
1219 	else
1220 	    lua_pushnil(L);
1221     }
1222     else
1223 	lua_pushnil(L);
1224     return 1;
1225 }
1226 
1227     static int
1228 luaV_blob_newindex(lua_State *L)
1229 {
1230     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1231     if (b->bv_lock)
1232 	luaL_error(L, "blob is locked");
1233     if (lua_isnumber(L, 2))
1234     {
1235 	long len = blob_len(b);
1236 	int idx = luaL_checkinteger(L, 2);
1237 	int val = luaL_checkinteger(L, 3);
1238 	if (idx < len || (idx == len && ga_grow(&b->bv_ga, 1) == OK))
1239 	{
1240 	    blob_set(b, idx, (char_u) val);
1241 	    if (idx == len)
1242 		++b->bv_ga.ga_len;
1243 	}
1244 	else
1245 	    luaL_error(L, "index out of range");
1246     }
1247     return 0;
1248 }
1249 
1250     static int
1251 luaV_blob_add(lua_State *L)
1252 {
1253     luaV_Blob *blo = luaV_checkudata(L, 1, LUAVIM_BLOB);
1254     blob_T *b = (blob_T *) luaV_checkcache(L, (void *) *blo);
1255     if (b->bv_lock)
1256 	luaL_error(L, "blob is locked");
1257     lua_settop(L, 2);
1258     if (!lua_isstring(L, 2))
1259 	luaL_error(L, "string expected, got %s", luaL_typename(L, 2));
1260     else
1261     {
1262 	size_t i, l = 0;
1263 	const char *s = lua_tolstring(L, 2, &l);
1264 
1265 	if (ga_grow(&b->bv_ga, (int)l) == OK)
1266 	    for (i = 0; i < l; ++i)
1267 		ga_append(&b->bv_ga, s[i]);
1268     }
1269     lua_settop(L, 1);
1270     return 1;
1271 }
1272 
1273 static const luaL_Reg luaV_Blob_mt[] = {
1274     {"__tostring", luaV_blob_tostring},
1275     {"__gc", luaV_blob_gc},
1276     {"__len", luaV_blob_len},
1277     {"__index", luaV_blob_index},
1278     {"__newindex", luaV_blob_newindex},
1279     {"add", luaV_blob_add},
1280     {NULL, NULL}
1281 };
1282 
1283 
1284 // =======   Funcref type   =======
1285 
1286     static luaV_Funcref *
1287 luaV_newfuncref(lua_State *L, char_u *name)
1288 {
1289     luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref));
1290 
1291     if (name != NULL)
1292     {
1293 	func_ref(name);
1294 	f->name = vim_strsave(name);
1295     }
1296     f->self = NULL;
1297     luaV_getfield(L, LUAVIM_FUNCREF);
1298     lua_setmetatable(L, -2);
1299     return f;
1300 }
1301 
1302     static luaV_Funcref *
1303 luaV_pushfuncref(lua_State *L, char_u *name)
1304 {
1305     return luaV_newfuncref(L, name);
1306 }
1307 
1308 
1309 luaV_type_tostring(funcref, LUAVIM_FUNCREF)
1310 
1311     static int
1312 luaV_funcref_gc(lua_State *L)
1313 {
1314     luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1315 
1316     func_unref(f->name);
1317     vim_free(f->name);
1318     // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self"
1319     // will be (or has been already) freed by Vim's garbage collection.
1320     return 0;
1321 }
1322 
1323 // equivalent to string(funcref)
1324     static int
1325 luaV_funcref_len(lua_State *L)
1326 {
1327     luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1328 
1329     lua_pushstring(L, (const char *) f->name);
1330     return 1;
1331 }
1332 
1333     static int
1334 luaV_funcref_call(lua_State *L)
1335 {
1336     luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1337     int i, n = lua_gettop(L) - 1; // #args
1338     int status = FAIL;
1339     typval_T args;
1340     typval_T rettv;
1341 
1342     args.v_type = VAR_LIST;
1343     args.vval.v_list = list_alloc();
1344     rettv.v_type = VAR_UNKNOWN; // as in clear_tv
1345     if (args.vval.v_list != NULL)
1346     {
1347 	typval_T v;
1348 
1349 	for (i = 0; i < n; i++)
1350 	{
1351 	    luaV_checktypval(L, i + 2, &v, "calling funcref");
1352 	    list_append_tv(args.vval.v_list, &v);
1353 	    clear_tv(&v);
1354 	}
1355 	status = func_call(f->name, &args, NULL, f->self, &rettv);
1356 	if (status == OK)
1357 	    luaV_pushtypval(L, &rettv);
1358 	clear_tv(&args);
1359 	clear_tv(&rettv);
1360     }
1361     if (status != OK)
1362 	luaL_error(L, "cannot call funcref");
1363     return 1;
1364 }
1365 
1366 static const luaL_Reg luaV_Funcref_mt[] = {
1367     {"__tostring", luaV_funcref_tostring},
1368     {"__gc", luaV_funcref_gc},
1369     {"__len", luaV_funcref_len},
1370     {"__call", luaV_funcref_call},
1371     {NULL, NULL}
1372 };
1373 
1374 
1375 // =======   Buffer type   =======
1376 
1377 luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER)
1378 luaV_pushtype(buf_T, buffer, luaV_Buffer)
1379 luaV_type_tostring(buffer, LUAVIM_BUFFER)
1380 
1381     static int
1382 luaV_buffer_len(lua_State *L)
1383 {
1384     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1385     lua_pushinteger(L, b->b_ml.ml_line_count);
1386     return 1;
1387 }
1388 
1389     static int
1390 luaV_buffer_call(lua_State *L)
1391 {
1392     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1393     lua_settop(L, 1);
1394     set_curbuf(b, DOBUF_SPLIT);
1395     return 1;
1396 }
1397 
1398     static int
1399 luaV_buffer_index(lua_State *L)
1400 {
1401     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1402     linenr_T n = (linenr_T) lua_tointeger(L, 2);
1403     if (n > 0 && n <= b->b_ml.ml_line_count)
1404 	luaV_pushline(L, b, n);
1405     else if (lua_isstring(L, 2))
1406     {
1407 	const char *s = lua_tostring(L, 2);
1408 	if (strncmp(s, "name", 4) == 0)
1409 	    lua_pushstring(L, (b->b_sfname == NULL)
1410 					? "" : (char *) b->b_sfname);
1411 	else if (strncmp(s, "fname", 5) == 0)
1412 	    lua_pushstring(L, (b->b_ffname == NULL)
1413 					? "" : (char *) b->b_ffname);
1414 	else if (strncmp(s, "number", 6) == 0)
1415 	    lua_pushinteger(L, b->b_fnum);
1416 	// methods
1417 	else if (strncmp(s,   "insert", 6) == 0
1418 		|| strncmp(s, "next", 4) == 0
1419 		|| strncmp(s, "previous", 8) == 0
1420 		|| strncmp(s, "isvalid", 7) == 0)
1421 	{
1422 	    lua_getmetatable(L, 1);
1423 	    lua_getfield(L, -1, s);
1424 	}
1425 	else
1426 	    lua_pushnil(L);
1427     }
1428     else
1429 	lua_pushnil(L);
1430     return 1;
1431 }
1432 
1433     static int
1434 luaV_buffer_newindex(lua_State *L)
1435 {
1436     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1437     linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
1438 #ifdef HAVE_SANDBOX
1439     luaV_checksandbox(L);
1440 #endif
1441     if (n < 1 || n > b->b_ml.ml_line_count)
1442 	luaL_error(L, "invalid line number");
1443     if (lua_isnil(L, 3)) // delete line
1444     {
1445 	buf_T *buf = curbuf;
1446 	curbuf = b;
1447 	if (u_savedel(n, 1L) == FAIL)
1448 	{
1449 	    curbuf = buf;
1450 	    luaL_error(L, "cannot save undo information");
1451 	}
1452 	else if (ml_delete(n) == FAIL)
1453 	{
1454 	    curbuf = buf;
1455 	    luaL_error(L, "cannot delete line");
1456 	}
1457 	else
1458 	{
1459 	    deleted_lines_mark(n, 1L);
1460 	    if (b == curwin->w_buffer) // fix cursor in current window?
1461 	    {
1462 		if (curwin->w_cursor.lnum >= n)
1463 		{
1464 		    if (curwin->w_cursor.lnum > n)
1465 		    {
1466 			curwin->w_cursor.lnum -= 1;
1467 			check_cursor_col();
1468 		    }
1469 		    else
1470 			check_cursor();
1471 		    changed_cline_bef_curs();
1472 		}
1473 		invalidate_botline();
1474 	    }
1475 	}
1476 	curbuf = buf;
1477     }
1478     else if (lua_isstring(L, 3)) // update line
1479     {
1480 	buf_T *buf = curbuf;
1481 	curbuf = b;
1482 	if (u_savesub(n) == FAIL)
1483 	{
1484 	    curbuf = buf;
1485 	    luaL_error(L, "cannot save undo information");
1486 	}
1487 	else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL)
1488 	{
1489 	    curbuf = buf;
1490 	    luaL_error(L, "cannot replace line");
1491 	}
1492 	else changed_bytes(n, 0);
1493 	curbuf = buf;
1494 	if (b == curwin->w_buffer)
1495 	    check_cursor_col();
1496     }
1497     else
1498 	luaL_error(L, "wrong argument to change line");
1499     return 0;
1500 }
1501 
1502     static int
1503 luaV_buffer_insert(lua_State *L)
1504 {
1505     luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1506     buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb);
1507     linenr_T last = b->b_ml.ml_line_count;
1508     linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
1509     buf_T *buf;
1510     luaL_checktype(L, 2, LUA_TSTRING);
1511 #ifdef HAVE_SANDBOX
1512     luaV_checksandbox(L);
1513 #endif
1514     // fix insertion line
1515     if (n < 0) n = 0;
1516     if (n > last) n = last;
1517     // insert
1518     buf = curbuf;
1519     curbuf = b;
1520     if (u_save(n, n + 1) == FAIL)
1521     {
1522 	curbuf = buf;
1523 	luaL_error(L, "cannot save undo information");
1524     }
1525     else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL)
1526     {
1527 	curbuf = buf;
1528 	luaL_error(L, "cannot insert line");
1529     }
1530     else
1531 	appended_lines_mark(n, 1L);
1532     curbuf = buf;
1533     update_screen(VALID);
1534     return 0;
1535 }
1536 
1537     static int
1538 luaV_buffer_next(lua_State *L)
1539 {
1540     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1541     buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
1542     luaV_pushbuffer(L, buf->b_next);
1543     return 1;
1544 }
1545 
1546     static int
1547 luaV_buffer_previous(lua_State *L)
1548 {
1549     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1550     buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
1551     luaV_pushbuffer(L, buf->b_prev);
1552     return 1;
1553 }
1554 
1555     static int
1556 luaV_buffer_isvalid(lua_State *L)
1557 {
1558     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1559     luaV_getudata(L, *b);
1560     lua_pushboolean(L, !lua_isnil(L, -1));
1561     return 1;
1562 }
1563 
1564 static const luaL_Reg luaV_Buffer_mt[] = {
1565     {"__tostring", luaV_buffer_tostring},
1566     {"__len", luaV_buffer_len},
1567     {"__call", luaV_buffer_call},
1568     {"__index", luaV_buffer_index},
1569     {"__newindex", luaV_buffer_newindex},
1570     {"insert", luaV_buffer_insert},
1571     {"next", luaV_buffer_next},
1572     {"previous", luaV_buffer_previous},
1573     {"isvalid", luaV_buffer_isvalid},
1574     {NULL, NULL}
1575 };
1576 
1577 
1578 // =======   Window type   =======
1579 
1580 luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW)
1581 luaV_pushtype(win_T, window, luaV_Window)
1582 luaV_type_tostring(window, LUAVIM_WINDOW)
1583 
1584     static int
1585 luaV_window_call(lua_State *L)
1586 {
1587     win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1588     lua_settop(L, 1);
1589     win_goto(w);
1590     return 1;
1591 }
1592 
1593     static int
1594 luaV_window_index(lua_State *L)
1595 {
1596     win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1597     const char *s = luaL_checkstring(L, 2);
1598     if (strncmp(s, "buffer", 6) == 0)
1599 	luaV_pushbuffer(L, w->w_buffer);
1600     else if (strncmp(s, "line", 4) == 0)
1601 	lua_pushinteger(L, w->w_cursor.lnum);
1602     else if (strncmp(s, "col", 3) == 0)
1603 	lua_pushinteger(L, w->w_cursor.col + 1);
1604     else if (strncmp(s, "width", 5) == 0)
1605 	lua_pushinteger(L, w->w_width);
1606     else if (strncmp(s, "height", 6) == 0)
1607 	lua_pushinteger(L, w->w_height);
1608     // methods
1609     else if (strncmp(s,   "next", 4) == 0
1610 	    || strncmp(s, "previous", 8) == 0
1611 	    || strncmp(s, "isvalid", 7) == 0)
1612     {
1613 	lua_getmetatable(L, 1);
1614 	lua_getfield(L, -1, s);
1615     }
1616     else
1617 	lua_pushnil(L);
1618     return 1;
1619 }
1620 
1621     static int
1622 luaV_window_newindex(lua_State *L)
1623 {
1624     win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1625     const char *s = luaL_checkstring(L, 2);
1626     int v = luaL_checkinteger(L, 3);
1627     if (strncmp(s, "line", 4) == 0)
1628     {
1629 #ifdef HAVE_SANDBOX
1630 	luaV_checksandbox(L);
1631 #endif
1632 	if (v < 1 || v > w->w_buffer->b_ml.ml_line_count)
1633 	    luaL_error(L, "line out of range");
1634 	w->w_cursor.lnum = v;
1635 	update_screen(VALID);
1636     }
1637     else if (strncmp(s, "col", 3) == 0)
1638     {
1639 #ifdef HAVE_SANDBOX
1640 	luaV_checksandbox(L);
1641 #endif
1642 	w->w_cursor.col = v - 1;
1643 	w->w_set_curswant = TRUE;
1644 	update_screen(VALID);
1645     }
1646     else if (strncmp(s, "width", 5) == 0)
1647     {
1648 	win_T *win = curwin;
1649 #ifdef FEAT_GUI
1650 	need_mouse_correct = TRUE;
1651 #endif
1652 	curwin = w;
1653 	win_setwidth(v);
1654 	curwin = win;
1655     }
1656     else if (strncmp(s, "height", 6) == 0)
1657     {
1658 	win_T *win = curwin;
1659 #ifdef FEAT_GUI
1660 	need_mouse_correct = TRUE;
1661 #endif
1662 	curwin = w;
1663 	win_setheight(v);
1664 	curwin = win;
1665     }
1666     else
1667 	luaL_error(L, "invalid window property: `%s'", s);
1668     return 0;
1669 }
1670 
1671     static int
1672 luaV_window_next(lua_State *L)
1673 {
1674     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
1675     win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
1676     luaV_pushwindow(L, win->w_next);
1677     return 1;
1678 }
1679 
1680     static int
1681 luaV_window_previous(lua_State *L)
1682 {
1683     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
1684     win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
1685     luaV_pushwindow(L, win->w_prev);
1686     return 1;
1687 }
1688 
1689     static int
1690 luaV_window_isvalid(lua_State *L)
1691 {
1692     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
1693     luaV_getudata(L, *w);
1694     lua_pushboolean(L, !lua_isnil(L, -1));
1695     return 1;
1696 }
1697 
1698 static const luaL_Reg luaV_Window_mt[] = {
1699     {"__tostring", luaV_window_tostring},
1700     {"__call", luaV_window_call},
1701     {"__index", luaV_window_index},
1702     {"__newindex", luaV_window_newindex},
1703     {"next", luaV_window_next},
1704     {"previous", luaV_window_previous},
1705     {"isvalid", luaV_window_isvalid},
1706     {NULL, NULL}
1707 };
1708 
1709 
1710 // =======   Vim module   =======
1711 
1712     static int
1713 luaV_print(lua_State *L)
1714 {
1715     int i, n = lua_gettop(L); // nargs
1716     const char *s;
1717     size_t l;
1718     luaL_Buffer b;
1719     luaL_buffinit(L, &b);
1720     lua_getglobal(L, "tostring");
1721     for (i = 1; i <= n; i++)
1722     {
1723 	lua_pushvalue(L, -1); // tostring
1724 	lua_pushvalue(L, i); // arg
1725 	lua_call(L, 1, 1);
1726 	s = lua_tolstring(L, -1, &l);
1727 	if (s == NULL)
1728 	    return luaL_error(L, "cannot convert to string");
1729 	if (i > 1) luaL_addchar(&b, ' '); // use space instead of tab
1730 	luaV_addlstring(&b, s, l, 0);
1731 	lua_pop(L, 1);
1732     }
1733     luaL_pushresult(&b);
1734     if (!got_int)
1735 	luaV_msg(L);
1736     return 0;
1737 }
1738 
1739     static int
1740 luaV_debug(lua_State *L)
1741 {
1742     lua_settop(L, 0);
1743     lua_getglobal(L, "vim");
1744     lua_getfield(L, -1, "eval");
1745     lua_remove(L, -2); // vim.eval at position 1
1746     for (;;)
1747     {
1748 	const char *input;
1749 	size_t l;
1750 	lua_pushvalue(L, 1); // vim.eval
1751 	lua_pushliteral(L, "input('lua_debug> ')");
1752 	lua_call(L, 1, 1); // return string
1753 	input = lua_tolstring(L, -1, &l);
1754 	if (l == 0 || strcmp(input, "cont") == 0)
1755 	    return 0;
1756 	msg_putchar('\n'); // avoid outputting on input line
1757 	if (luaL_loadbuffer(L, input, l, "=(debug command)")
1758 		|| lua_pcall(L, 0, 0, 0))
1759 	    luaV_emsg(L);
1760 	lua_settop(L, 1); // remove eventual returns, but keep vim.eval
1761     }
1762 }
1763 
1764     static int
1765 luaV_command(lua_State *L)
1766 {
1767     do_cmdline_cmd((char_u *) luaL_checkstring(L, 1));
1768     update_screen(VALID);
1769     return 0;
1770 }
1771 
1772     static int
1773 luaV_eval(lua_State *L)
1774 {
1775     typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL);
1776     if (tv == NULL) luaL_error(L, "invalid expression");
1777     luaV_pushtypval(L, tv);
1778     free_tv(tv);
1779     return 1;
1780 }
1781 
1782     static int
1783 luaV_beep(lua_State *L UNUSED)
1784 {
1785     vim_beep(BO_LANG);
1786     return 0;
1787 }
1788 
1789     static int
1790 luaV_line(lua_State *L)
1791 {
1792     luaV_pushline(L, curbuf, curwin->w_cursor.lnum);
1793     return 1;
1794 }
1795 
1796     static int
1797 luaV_list(lua_State *L)
1798 {
1799     list_T *l;
1800     int initarg = !lua_isnoneornil(L, 1);
1801 
1802     if (initarg && lua_type(L, 1) != LUA_TTABLE)
1803 	luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
1804     l = list_alloc();
1805     if (l == NULL)
1806 	lua_pushnil(L);
1807     else
1808     {
1809 	luaV_newlist(L, l);
1810 	if (initarg) // traverse table to init list
1811 	{
1812 	    int notnil, i = 0;
1813 	    typval_T v;
1814 	    do
1815 	    {
1816 		lua_rawgeti(L, 1, ++i);
1817 		notnil = !lua_isnil(L, -1);
1818 		if (notnil)
1819 		{
1820 		    luaV_checktypval(L, -1, &v, "vim.list");
1821 		    list_append_tv(l, &v);
1822 		    clear_tv(&v);
1823 		}
1824 		lua_pop(L, 1); // value
1825 	    } while (notnil);
1826 	}
1827     }
1828     return 1;
1829 }
1830 
1831     static int
1832 luaV_dict(lua_State *L)
1833 {
1834     dict_T *d;
1835     int initarg = !lua_isnoneornil(L, 1);
1836 
1837     if (initarg && lua_type(L, 1) != LUA_TTABLE)
1838 	luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
1839     d = dict_alloc();
1840     if (d == NULL)
1841 	lua_pushnil(L);
1842     else
1843     {
1844 	luaV_newdict(L, d);
1845 	if (initarg) // traverse table to init dict
1846 	{
1847 	    lua_pushnil(L);
1848 	    while (lua_next(L, 1))
1849 	    {
1850 		char_u *key;
1851 		dictitem_T *di;
1852 		typval_T v;
1853 
1854 		lua_pushvalue(L, -2); // dup key in case it's a number
1855 		key = (char_u *) lua_tostring(L, -1);
1856 		if (key == NULL)
1857 		{
1858 		    lua_pushnil(L);
1859 		    return 1;
1860 		}
1861 		if (*key == NUL)
1862 		    luaL_error(L, "table has empty key");
1863 		luaV_checktypval(L, -2, &v, "vim.dict"); // value
1864 		di = dictitem_alloc(key);
1865 		if (di == NULL || dict_add(d, di) == FAIL)
1866 		{
1867 		    vim_free(di);
1868 		    lua_pushnil(L);
1869 		    return 1;
1870 		}
1871 		di->di_tv = v;
1872 		lua_pop(L, 2); // key copy and value
1873 	    }
1874 	}
1875     }
1876     return 1;
1877 }
1878 
1879     static int
1880 luaV_blob(lua_State *L)
1881 {
1882     blob_T *b;
1883     int initarg = !lua_isnoneornil(L, 1);
1884 
1885     if (initarg && !lua_isstring(L, 1))
1886 	luaL_error(L, "string expected, got %s", luaL_typename(L, 1));
1887     b = blob_alloc();
1888     if (b == NULL)
1889 	lua_pushnil(L);
1890     else
1891     {
1892 	luaV_newblob(L, b);
1893 	if (initarg)
1894 	{
1895 	    size_t i, l = 0;
1896 	    const char *s = lua_tolstring(L, 1, &l);
1897 
1898 	    if (ga_grow(&b->bv_ga, (int)l) == OK)
1899 		for (i = 0; i < l; ++i)
1900 		    ga_append(&b->bv_ga, s[i]);
1901 	}
1902     }
1903     return 1;
1904 }
1905 
1906     static int
1907 luaV_funcref(lua_State *L)
1908 {
1909     const char *name = luaL_checkstring(L, 1);
1910     // note: not checking if function exists (needs function_exists)
1911     if (name == NULL || *name == NUL || VIM_ISDIGIT(*name))
1912 	luaL_error(L, "invalid function name: %s", name);
1913     luaV_newfuncref(L, (char_u *) name);
1914     return 1;
1915 }
1916 
1917     static int
1918 luaV_buffer(lua_State *L)
1919 {
1920     buf_T *buf;
1921     if (lua_isstring(L, 1)) // get by number or name?
1922     {
1923 	if (lua_isnumber(L, 1)) // by number?
1924 	{
1925 	    int n = lua_tointeger(L, 1);
1926 	    FOR_ALL_BUFFERS(buf)
1927 		if (buf->b_fnum == n) break;
1928 	}
1929 	else // by name
1930 	{
1931 	    size_t l;
1932 	    const char *s = lua_tolstring(L, 1, &l);
1933 	    FOR_ALL_BUFFERS(buf)
1934 	    {
1935 		if (buf->b_ffname == NULL || buf->b_sfname == NULL)
1936 		{
1937 		    if (l == 0) break;
1938 		}
1939 		else if (strncmp(s, (char *)buf->b_ffname, l) == 0
1940 			|| strncmp(s, (char *)buf->b_sfname, l) == 0)
1941 		    break;
1942 	    }
1943 	}
1944     }
1945     else
1946 	buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; // first buffer?
1947     luaV_pushbuffer(L, buf);
1948     return 1;
1949 }
1950 
1951     static int
1952 luaV_window(lua_State *L)
1953 {
1954     win_T *win;
1955     if (lua_isnumber(L, 1)) // get by number?
1956     {
1957 	int n = lua_tointeger(L, 1);
1958 	for (win = firstwin; win != NULL; win = win->w_next, n--)
1959 	    if (n == 1) break;
1960     }
1961     else
1962 	win = (lua_toboolean(L, 1)) ? firstwin : curwin; // first window?
1963     luaV_pushwindow(L, win);
1964     return 1;
1965 }
1966 
1967     static int
1968 luaV_open(lua_State *L)
1969 {
1970     char_u *s = NULL;
1971 #ifdef HAVE_SANDBOX
1972     luaV_checksandbox(L);
1973 #endif
1974     if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1);
1975     luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED));
1976     return 1;
1977 }
1978 
1979     static int
1980 luaV_type(lua_State *L)
1981 {
1982     luaL_checkany(L, 1);
1983     if (lua_type(L, 1) == LUA_TUSERDATA) // check vim udata?
1984     {
1985 	lua_settop(L, 1);
1986 	if (lua_getmetatable(L, 1))
1987 	{
1988 	    luaV_getfield(L, LUAVIM_LIST);
1989 	    if (lua_rawequal(L, -1, 2))
1990 	    {
1991 		lua_pushstring(L, "list");
1992 		return 1;
1993 	    }
1994 	    luaV_getfield(L, LUAVIM_DICT);
1995 	    if (lua_rawequal(L, -1, 2))
1996 	    {
1997 		lua_pushstring(L, "dict");
1998 		return 1;
1999 	    }
2000 	    luaV_getfield(L, LUAVIM_BLOB);
2001 	    if (lua_rawequal(L, -1, 2))
2002 	    {
2003 		lua_pushstring(L, "blob");
2004 		return 1;
2005 	    }
2006 	    luaV_getfield(L, LUAVIM_FUNCREF);
2007 	    if (lua_rawequal(L, -1, 2))
2008 	    {
2009 		lua_pushstring(L, "funcref");
2010 		return 1;
2011 	    }
2012 	    luaV_getfield(L, LUAVIM_BUFFER);
2013 	    if (lua_rawequal(L, -1, 2))
2014 	    {
2015 		lua_pushstring(L, "buffer");
2016 		return 1;
2017 	    }
2018 	    luaV_getfield(L, LUAVIM_WINDOW);
2019 	    if (lua_rawequal(L, -1, 2))
2020 	    {
2021 		lua_pushstring(L, "window");
2022 		return 1;
2023 	    }
2024 	}
2025     }
2026     lua_pushstring(L, luaL_typename(L, 1)); // fallback
2027     return 1;
2028 }
2029 
2030     static int
2031 luaV_call(lua_State *L)
2032 {
2033     int		argc = lua_gettop(L) - 1;
2034     size_t	funcname_len;
2035     char_u	*funcname;
2036     char	*error = NULL;
2037     typval_T	rettv;
2038     typval_T	argv[MAX_FUNC_ARGS + 1];
2039     int		i = 0;
2040 
2041     if (argc > MAX_FUNC_ARGS)
2042 	return luaL_error(L, "Function called with too many arguments");
2043 
2044     funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len);
2045 
2046     for (; i < argc; i++)
2047     {
2048 	if (luaV_totypval(L, i + 2, &argv[i]) == FAIL)
2049 	{
2050 	    error = "lua: cannot convert value";
2051 	    goto free_vim_args;
2052 	}
2053     }
2054 
2055     argv[argc].v_type = VAR_UNKNOWN;
2056 
2057     if (call_vim_function(funcname, argc, argv, &rettv) == FAIL)
2058     {
2059 	error = "lua: call_vim_function failed";
2060 	goto free_vim_args;
2061     }
2062 
2063     luaV_pushtypval(L, &rettv);
2064     clear_tv(&rettv);
2065 
2066 free_vim_args:
2067     while (i > 0)
2068 	clear_tv(&argv[--i]);
2069 
2070     if (error == NULL)
2071 	return 1;
2072     else
2073 	return luaL_error(L, error);
2074 }
2075 
2076 static const luaL_Reg luaV_module[] = {
2077     {"command", luaV_command},
2078     {"eval", luaV_eval},
2079     {"beep", luaV_beep},
2080     {"line", luaV_line},
2081     {"list", luaV_list},
2082     {"dict", luaV_dict},
2083     {"blob", luaV_blob},
2084     {"funcref", luaV_funcref},
2085     {"buffer", luaV_buffer},
2086     {"window", luaV_window},
2087     {"open", luaV_open},
2088     {"type", luaV_type},
2089     {"call", luaV_call},
2090     {NULL, NULL}
2091 };
2092 
2093 /*
2094  * for freeing list, dict, buffer and window objects; lightuserdata as arg
2095  */
2096     static int
2097 luaV_free(lua_State *L)
2098 {
2099     lua_pushnil(L);
2100     luaV_setudata(L, lua_touserdata(L, 1));
2101     return 0;
2102 }
2103 
2104     static int
2105 luaV_luaeval(lua_State *L)
2106 {
2107     luaL_Buffer b;
2108     size_t l;
2109     const char *str = lua_tolstring(L, 1, &l);
2110     typval_T *arg = (typval_T *) lua_touserdata(L, 2);
2111     typval_T *rettv = (typval_T *) lua_touserdata(L, 3);
2112     luaL_buffinit(L, &b);
2113     luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1);
2114     luaL_addlstring(&b, str, l);
2115     luaL_pushresult(&b);
2116     str = lua_tolstring(L, -1, &l);
2117     if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) // compile error?
2118     {
2119 	luaV_emsg(L);
2120 	return 0;
2121     }
2122     luaV_pushtypval(L, arg);
2123     if (lua_pcall(L, 1, 1, 0)) // running error?
2124     {
2125 	luaV_emsg(L);
2126 	return 0;
2127     }
2128     if (luaV_totypval(L, -1, rettv) == FAIL)
2129 	emsg("luaeval: cannot convert value");
2130     return 0;
2131 }
2132 
2133     static int
2134 luaV_setref(lua_State *L)
2135 {
2136     int copyID = lua_tointeger(L, 1);
2137     int abort = FALSE;
2138 
2139     luaV_getfield(L, LUAVIM_LIST);
2140     luaV_getfield(L, LUAVIM_DICT);
2141     luaV_getfield(L, LUAVIM_FUNCREF);
2142     lua_pushnil(L);
2143     // traverse cache table
2144     while (!abort && lua_next(L, lua_upvalueindex(1)) != 0)
2145     {
2146 	lua_getmetatable(L, -1);
2147 	if (lua_rawequal(L, -1, 2)) // list?
2148 	{
2149 	    list_T *l = (list_T *)lua_touserdata(L, 5); // key
2150 
2151 	    abort = set_ref_in_list(l, copyID);
2152 	}
2153 	else if (lua_rawequal(L, -1, 3)) // dict?
2154 	{
2155 	    dict_T *d = (dict_T *)lua_touserdata(L, 5); // key
2156 
2157 	    abort = set_ref_in_dict(d, copyID);
2158 	}
2159 	else if (lua_rawequal(L, -1, 4)) // funcref?
2160 	{
2161 	    luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key
2162 
2163 	    abort = set_ref_in_dict(f->self, copyID);
2164 	}
2165 	lua_pop(L, 2); // metatable and value
2166     }
2167     lua_pushinteger(L, abort);
2168     return 1;
2169 }
2170 
2171 #define LUA_VIM_FN_CODE \
2172     "vim.fn = setmetatable({}, {\n"\
2173     "  __index = function (t, key)\n"\
2174     "    local function _fn(...)\n"\
2175     "      return vim.call(key, ...)\n"\
2176     "    end\n"\
2177     "    t[key] = _fn\n"\
2178     "    return _fn\n"\
2179     "  end\n"\
2180     " })"
2181 
2182 #define LUA_VIM_UPDATE_PACKAGE_PATHS \
2183     "local last_vim_paths = {}\n"\
2184     "vim._update_package_paths = function ()\n"\
2185     "  local cur_vim_paths = {}\n"\
2186     "  local function split(s, delimiter)\n"\
2187     "    result = {}\n"\
2188     "    for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\
2189     "      table.insert(result, match)\n"\
2190     "    end\n"\
2191     "    return result\n"\
2192     "  end\n"\
2193     "  local rtps = split(vim.eval('&runtimepath'), ',')\n"\
2194     "  local sep = package.config:sub(1, 1)\n"\
2195     "  for _, key in ipairs({'path', 'cpath'}) do\n"\
2196     "    local orig_str = package[key] .. ';'\n"\
2197     "    local pathtrails_ordered = {}\n"\
2198     "    -- Note: ignores trailing item without trailing `;`. Not using something\n"\
2199     "    -- simpler in order to preserve empty items (stand for default path).\n"\
2200     "    local orig = {}\n"\
2201     "    for s in orig_str:gmatch('[^;]*;') do\n"\
2202     "      s = s:sub(1, -2)  -- Strip trailing semicolon\n"\
2203     "      orig[#orig + 1] = s\n"\
2204     "    end\n"\
2205     "    if key == 'path' then\n"\
2206     "      -- /?.lua and /?/init.lua\n"\
2207     "      pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\
2208     "    else\n"\
2209     "      local pathtrails = {}\n"\
2210     "      for _, s in ipairs(orig) do\n"\
2211     "        -- Find out path patterns. pathtrail should contain something like\n"\
2212     "        -- /?.so, \?.dll. This allows not to bother determining what correct\n"\
2213     "        -- suffixes are.\n"\
2214     "        local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\
2215     "        if pathtrail and not pathtrails[pathtrail] then\n"\
2216     "          pathtrails[pathtrail] = true\n"\
2217     "          pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\
2218     "        end\n"\
2219     "      end\n"\
2220     "    end\n"\
2221     "    local new = {}\n"\
2222     "    for _, rtp in ipairs(rtps) do\n"\
2223     "      if not rtp:match(';') then\n"\
2224     "        for _, pathtrail in pairs(pathtrails_ordered) do\n"\
2225     "          local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\
2226     "          -- Always keep paths from &runtimepath at the start:\n"\
2227     "          -- append them here disregarding orig possibly containing one of them.\n"\
2228     "          new[#new + 1] = new_path\n"\
2229     "          cur_vim_paths[new_path] = true\n"\
2230     "        end\n"\
2231     "      end\n"\
2232     "    end\n"\
2233     "    for _, orig_path in ipairs(orig) do\n"\
2234     "      -- Handle removing obsolete paths originating from &runtimepath: such\n"\
2235     "      -- paths either belong to cur_nvim_paths and were already added above or\n"\
2236     "      -- to last_nvim_paths and should not be added at all if corresponding\n"\
2237     "      -- entry was removed from &runtimepath list.\n"\
2238     "      if not (cur_vim_paths[orig_path] or last_vim_paths[orig_path]) then\n"\
2239     "        new[#new + 1] = orig_path\n"\
2240     "      end\n"\
2241     "    end\n"\
2242     "    package[key] = table.concat(new, ';')\n"\
2243     "  end\n"\
2244     "  last_vim_paths = cur_vim_paths\n"\
2245     "end"
2246 
2247     static int
2248 luaopen_vim(lua_State *L)
2249 {
2250     // set cache table
2251     lua_newtable(L);
2252     lua_newtable(L);
2253     lua_pushstring(L, "v");
2254     lua_setfield(L, -2, "__mode");
2255     lua_setmetatable(L, -2); // cache is weak-valued
2256     // print
2257     lua_pushcfunction(L, luaV_print);
2258     lua_setglobal(L, "print");
2259     // debug.debug
2260     lua_getglobal(L, "debug");
2261     lua_pushcfunction(L, luaV_debug);
2262     lua_setfield(L, -2, "debug");
2263     lua_pop(L, 1);
2264     // free
2265     lua_pushlightuserdata(L, (void *) LUAVIM_FREE);
2266     lua_pushvalue(L, 1); // cache table
2267     lua_pushcclosure(L, luaV_free, 1);
2268     lua_rawset(L, LUA_REGISTRYINDEX);
2269     // luaeval
2270     lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL);
2271     lua_pushvalue(L, 1); // cache table
2272     lua_pushcclosure(L, luaV_luaeval, 1);
2273     lua_rawset(L, LUA_REGISTRYINDEX);
2274     // setref
2275     lua_pushlightuserdata(L, (void *) LUAVIM_SETREF);
2276     lua_pushvalue(L, 1); // cache table
2277     lua_pushcclosure(L, luaV_setref, 1);
2278     lua_rawset(L, LUA_REGISTRYINDEX);
2279     // register
2280     luaV_newmetatable(L, LUAVIM_LIST);
2281     lua_pushvalue(L, 1);
2282     luaV_openlib(L, luaV_List_mt, 1);
2283     luaV_newmetatable(L, LUAVIM_DICT);
2284     lua_pushvalue(L, 1);
2285     luaV_openlib(L, luaV_Dict_mt, 1);
2286     luaV_newmetatable(L, LUAVIM_BLOB);
2287     lua_pushvalue(L, 1);
2288     luaV_openlib(L, luaV_Blob_mt, 1);
2289     luaV_newmetatable(L, LUAVIM_FUNCREF);
2290     lua_pushvalue(L, 1);
2291     luaV_openlib(L, luaV_Funcref_mt, 1);
2292     luaV_newmetatable(L, LUAVIM_BUFFER);
2293     lua_pushvalue(L, 1); // cache table
2294     luaV_openlib(L, luaV_Buffer_mt, 1);
2295     luaV_newmetatable(L, LUAVIM_WINDOW);
2296     lua_pushvalue(L, 1); // cache table
2297     luaV_openlib(L, luaV_Window_mt, 1);
2298     lua_newtable(L); // vim table
2299     lua_pushvalue(L, 1); // cache table
2300     luaV_openlib(L, luaV_module, 1);
2301     lua_setglobal(L, LUAVIM_NAME);
2302     // custom code
2303     (void)luaL_dostring(L, LUA_VIM_FN_CODE);
2304     (void)luaL_dostring(L, LUA_VIM_UPDATE_PACKAGE_PATHS);
2305 
2306     lua_getglobal(L, "vim");
2307     lua_getfield(L, -1, "_update_package_paths");
2308 
2309     if (lua_pcall(L, 0, 0, 0))
2310 	luaV_emsg(L);
2311 
2312     return 0;
2313 }
2314 
2315     static lua_State *
2316 luaV_newstate(void)
2317 {
2318     lua_State *L = luaL_newstate();
2319     luaL_openlibs(L); // core libs
2320     lua_pushcfunction(L, luaopen_vim); // vim
2321     lua_call(L, 0, 0);
2322     return L;
2323 }
2324 
2325     static void
2326 luaV_setrange(lua_State *L, int line1, int line2)
2327 {
2328     lua_getglobal(L, LUAVIM_NAME);
2329     lua_pushinteger(L, line1);
2330     lua_setfield(L, -2, "firstline");
2331     lua_pushinteger(L, line2);
2332     lua_setfield(L, -2, "lastline");
2333     lua_pop(L, 1); // vim table
2334 }
2335 
2336 
2337 // =======   Interface   =======
2338 
2339 static lua_State *L = NULL;
2340 
2341     static int
2342 lua_isopen(void)
2343 {
2344     return L != NULL;
2345 }
2346 
2347     static int
2348 lua_init(void)
2349 {
2350     if (!lua_isopen())
2351     {
2352 #ifdef DYNAMIC_LUA
2353 	if (!lua_enabled(TRUE))
2354 	{
2355 	    emsg(_("Lua library cannot be loaded."));
2356 	    return FAIL;
2357 	}
2358 #endif
2359 	L = luaV_newstate();
2360     }
2361     return OK;
2362 }
2363 
2364     void
2365 lua_end(void)
2366 {
2367     if (lua_isopen())
2368     {
2369 	lua_close(L);
2370 	L = NULL;
2371     }
2372 }
2373 
2374 /*
2375  * ex commands
2376  */
2377     void
2378 ex_lua(exarg_T *eap)
2379 {
2380     char *script = (char *)script_get(eap, eap->arg);
2381 
2382     if (!eap->skip && lua_init() == OK)
2383     {
2384 	char *s = script != NULL ? script : (char *)eap->arg;
2385 
2386 	luaV_setrange(L, eap->line1, eap->line2);
2387 	if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME)
2388 		|| lua_pcall(L, 0, 0, 0))
2389 	    luaV_emsg(L);
2390     }
2391     if (script != NULL)
2392 	vim_free(script);
2393 }
2394 
2395     void
2396 ex_luado(exarg_T *eap)
2397 {
2398     linenr_T l;
2399     const char *s = (const char *) eap->arg;
2400     luaL_Buffer b;
2401     size_t len;
2402     buf_T *was_curbuf = curbuf;
2403 
2404     if (lua_init() == FAIL) return;
2405     if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
2406     {
2407 	emsg(_("cannot save undo information"));
2408 	return;
2409     }
2410     luaV_setrange(L, eap->line1, eap->line2);
2411     luaL_buffinit(L, &b);
2412     luaL_addlstring(&b, "return function(line, linenr) ", 30); // header
2413     luaL_addlstring(&b, s, strlen(s));
2414     luaL_addlstring(&b, " end", 4); // footer
2415     luaL_pushresult(&b);
2416     s = lua_tolstring(L, -1, &len);
2417     if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME))
2418     {
2419 	luaV_emsg(L);
2420 	lua_pop(L, 1); // function body
2421 	return;
2422     }
2423     lua_call(L, 0, 1);
2424     lua_replace(L, -2); // function -> body
2425     for (l = eap->line1; l <= eap->line2; l++)
2426     {
2427 	// Check the line number, the command may have deleted lines.
2428 	if (l > curbuf->b_ml.ml_line_count)
2429 	    break;
2430 
2431 	lua_pushvalue(L, -1); // function
2432 	luaV_pushline(L, curbuf, l); // current line as arg
2433 	lua_pushinteger(L, l); // current line number as arg
2434 	if (lua_pcall(L, 2, 1, 0))
2435 	{
2436 	    luaV_emsg(L);
2437 	    break;
2438 	}
2439 	// Catch the command switching to another buffer.
2440 	if (curbuf != was_curbuf)
2441 	    break;
2442 	if (lua_isstring(L, -1)) // update line?
2443 	{
2444 #ifdef HAVE_SANDBOX
2445 	    luaV_checksandbox(L);
2446 #endif
2447 	    ml_replace(l, luaV_toline(L, -1), TRUE);
2448 	    changed_bytes(l, 0);
2449 	    lua_pop(L, 1); // result from luaV_toline
2450 	}
2451 	lua_pop(L, 1); // line
2452     }
2453     lua_pop(L, 1); // function
2454     check_cursor();
2455     update_screen(NOT_VALID);
2456 }
2457 
2458     void
2459 ex_luafile(exarg_T *eap)
2460 {
2461     if (lua_init() == FAIL)
2462 	return;
2463     if (!eap->skip)
2464     {
2465 	luaV_setrange(L, eap->line1, eap->line2);
2466 	if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0))
2467 	    luaV_emsg(L);
2468     }
2469 }
2470 
2471 #define luaV_freetype(typ,tname) \
2472 	void \
2473     lua_##tname##_free(typ *o) \
2474     { \
2475 	if (!lua_isopen()) return; \
2476 	luaV_getfield(L, LUAVIM_FREE); \
2477 	lua_pushlightuserdata(L, (void *) o); \
2478 	lua_call(L, 1, 0); \
2479     }
2480 
2481 luaV_freetype(buf_T, buffer)
2482 luaV_freetype(win_T, window)
2483 
2484     void
2485 do_luaeval(char_u *str, typval_T *arg, typval_T *rettv)
2486 {
2487     lua_init();
2488     luaV_getfield(L, LUAVIM_LUAEVAL);
2489     lua_pushstring(L, (char *) str);
2490     lua_pushlightuserdata(L, (void *) arg);
2491     lua_pushlightuserdata(L, (void *) rettv);
2492     lua_call(L, 3, 0);
2493 }
2494 
2495     int
2496 set_ref_in_lua(int copyID)
2497 {
2498     int aborted = 0;
2499 
2500     if (lua_isopen())
2501     {
2502 	luaV_getfield(L, LUAVIM_SETREF);
2503 	// call the function with 1 arg, getting 1 result back
2504 	lua_pushinteger(L, copyID);
2505 	lua_call(L, 1, 1);
2506 	// get the result
2507 	aborted = lua_tointeger(L, -1);
2508 	// pop result off the stack
2509 	lua_pop(L, 1);
2510     }
2511     return aborted;
2512 }
2513 
2514     void
2515 update_package_paths_in_lua()
2516 {
2517     if (lua_isopen())
2518     {
2519 	lua_getglobal(L, "vim");
2520 	lua_getfield(L, -1, "_update_package_paths");
2521 
2522 	if (lua_pcall(L, 0, 0, 0))
2523 	    luaV_emsg(L);
2524     }
2525 }
2526 
2527 /*
2528  * Native C function callback
2529  */
2530     static int
2531 luaV_call_lua_func(
2532 	int	 argcount,
2533 	typval_T *argvars,
2534 	typval_T *rettv,
2535 	void	 *state)
2536 {
2537     int i;
2538     int luaargcount = argcount;
2539     luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
2540     lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
2541 
2542     if (funcstate->lua_tableref != LUA_NOREF)
2543     {
2544 	// First arg for metatable __call method is a table
2545 	luaargcount += 1;
2546 	lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
2547     }
2548 
2549     for (i = 0; i < argcount; ++i)
2550 	luaV_pushtypval(funcstate->L, &argvars[i]);
2551 
2552     if (lua_pcall(funcstate->L, luaargcount, 1, 0))
2553     {
2554 	luaV_emsg(funcstate->L);
2555 	return FCERR_OTHER;
2556     }
2557 
2558     luaV_checktypval(funcstate->L, -1, rettv, "get return value");
2559     return FCERR_NONE;
2560 }
2561 
2562 /*
2563  * Free up any lua references held by the func state.
2564  */
2565     static void
2566 luaV_call_lua_func_free(void *state)
2567 {
2568     luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
2569     luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
2570     funcstate->L = NULL;
2571     if (funcstate->lua_tableref != LUA_NOREF)
2572 	luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
2573     VIM_CLEAR(funcstate);
2574 }
2575 
2576 #endif
2577