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