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