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