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