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