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