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