executor.c (67858B)
1 #include <assert.h> 2 #include <inttypes.h> 3 #include <lauxlib.h> 4 #include <lua.h> 5 #include <lualib.h> 6 #include <math.h> 7 #include <stddef.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <tree_sitter/api.h> 12 #include <uv.h> 13 14 #include "klib/kvec.h" 15 #include "luv/luv.h" 16 #include "nvim/api/extmark.h" 17 #include "nvim/api/private/defs.h" 18 #include "nvim/api/private/helpers.h" 19 #include "nvim/api/ui.h" 20 #include "nvim/ascii_defs.h" 21 #include "nvim/buffer_defs.h" 22 #include "nvim/change.h" 23 #include "nvim/cmdexpand_defs.h" 24 #include "nvim/cursor.h" 25 #include "nvim/drawscreen.h" 26 #include "nvim/errors.h" 27 #include "nvim/eval/funcs.h" 28 #include "nvim/eval/typval.h" 29 #include "nvim/eval/typval_defs.h" 30 #include "nvim/eval/userfunc.h" 31 #include "nvim/event/defs.h" 32 #include "nvim/event/loop.h" 33 #include "nvim/event/multiqueue.h" 34 #include "nvim/event/time.h" 35 #include "nvim/ex_cmds.h" 36 #include "nvim/ex_cmds_defs.h" 37 #include "nvim/ex_getln.h" 38 #include "nvim/garray.h" 39 #include "nvim/garray_defs.h" 40 #include "nvim/getchar.h" 41 #include "nvim/gettext_defs.h" 42 #include "nvim/globals.h" 43 #include "nvim/keycodes.h" 44 #include "nvim/lua/converter.h" 45 #include "nvim/lua/executor.h" 46 #include "nvim/lua/stdlib.h" 47 #include "nvim/lua/treesitter.h" 48 #include "nvim/macros_defs.h" 49 #include "nvim/main.h" 50 #include "nvim/mbyte_defs.h" 51 #include "nvim/memline.h" 52 #include "nvim/memory.h" 53 #include "nvim/memory_defs.h" 54 #include "nvim/message.h" 55 #include "nvim/message_defs.h" 56 #include "nvim/msgpack_rpc/channel.h" 57 #include "nvim/option_vars.h" 58 #include "nvim/os/fileio.h" 59 #include "nvim/os/fileio_defs.h" 60 #include "nvim/os/os.h" 61 #include "nvim/path.h" 62 #include "nvim/pos_defs.h" 63 #include "nvim/profile.h" 64 #include "nvim/runtime.h" 65 #include "nvim/runtime_defs.h" 66 #include "nvim/strings.h" 67 #include "nvim/ui.h" 68 #include "nvim/ui_defs.h" 69 #include "nvim/undo.h" 70 #include "nvim/usercmd.h" 71 #include "nvim/vim_defs.h" 72 #include "nvim/window.h" 73 74 #ifndef MSWIN 75 # include <pthread.h> 76 #endif 77 78 static int in_fast_callback = 0; 79 static bool in_script = false; 80 81 // Initialized in nlua_init(). 82 static lua_State *global_lstate = NULL; 83 84 // Tracks the currently executing Lua thread (main or coroutine). 85 lua_State *active_lstate = NULL; 86 87 static LuaRef require_ref = LUA_REFNIL; 88 89 static uv_thread_t main_thread; 90 91 typedef struct { 92 Error err; 93 String lua_err_str; 94 } LuaError; 95 96 typedef struct { 97 char *name; 98 const uint8_t *data; 99 size_t size; 100 } ModuleDef; 101 102 #include "lua/executor.c.generated.h" 103 #include "lua/vim_module.generated.h" 104 105 #define PUSH_ALL_TYPVALS(lstate, args, argcount, special) \ 106 for (int i = 0; i < argcount; i++) { \ 107 if (args[i].v_type == VAR_UNKNOWN) { \ 108 lua_pushnil(lstate); \ 109 } else { \ 110 nlua_push_typval(lstate, &args[i], (special) ? kNluaPushSpecial : 0); \ 111 } \ 112 } 113 114 #if __has_feature(address_sanitizer) 115 static bool nlua_track_refs = false; 116 # define NLUA_TRACK_REFS 117 #endif 118 119 typedef enum luv_err_type { 120 kCallback, 121 kThread, 122 kThreadCallback, 123 } luv_err_t; 124 125 lua_State *get_global_lstate(void) 126 { 127 return global_lstate; 128 } 129 130 /// Gets the Lua error at top of stack as a string, possibly modifying it in-place (but doesn't 131 /// change stack height). 132 /// 133 /// The returned string points to memory on the Lua stack. Use or duplicate it before using 134 /// `lstate` again. 135 /// 136 /// @param[out] len length of error (can be NULL) 137 static const char *nlua_get_error(lua_State *lstate, size_t *len) 138 { 139 if (luaL_getmetafield(lstate, -1, "__tostring")) { 140 if (lua_isfunction(lstate, -1) && luaL_callmeta(lstate, -2, "__tostring")) { 141 // call __tostring, convert the result and replace error with it 142 lua_replace(lstate, -3); 143 } 144 // pop __tostring. 145 lua_pop(lstate, 1); 146 } 147 148 return lua_tolstring(lstate, -1, len); 149 } 150 151 /// Converts a Lua error into a Vim error message. 152 /// 153 /// @param lstate Lua interpreter state. 154 /// @param[in] msg Message base, must contain one `%.*s`. 155 void nlua_error(lua_State *const lstate, const char *const msg) 156 FUNC_ATTR_NONNULL_ALL 157 { 158 size_t len; 159 const char *str = nlua_get_error(lstate, &len); 160 161 if (in_script) { 162 fprintf(stderr, msg, (int)len, str); 163 fprintf(stderr, "\n"); 164 } else { 165 semsg_multiline("lua_error", msg, (int)len, str); 166 } 167 168 lua_pop(lstate, 1); 169 } 170 171 /// Like lua_pcall, but use debug.traceback as errfunc. 172 /// 173 /// @param lstate Lua interpreter state 174 /// @param[in] nargs Number of arguments expected by the function being called. 175 /// @param[in] nresults Number of results the function returns. 176 int nlua_pcall(lua_State *lstate, int nargs, int nresults) 177 { 178 lua_getglobal(lstate, "debug"); 179 lua_getfield(lstate, -1, "traceback"); 180 lua_remove(lstate, -2); 181 lua_insert(lstate, -2 - nargs); 182 int pre_top = lua_gettop(lstate); 183 int status = lua_pcall(lstate, nargs, nresults, -2 - nargs); 184 if (status) { 185 lua_remove(lstate, -2); 186 } else { 187 if (nresults == LUA_MULTRET) { 188 nresults = lua_gettop(lstate) - (pre_top - nargs - 1); 189 } 190 lua_remove(lstate, -1 - nresults); 191 } 192 return status; 193 } 194 195 static void nlua_luv_error_event(void **argv) 196 { 197 char *error = (char *)argv[0]; 198 luv_err_t type = (luv_err_t)(intptr_t)argv[1]; 199 switch (type) { 200 case kCallback: 201 semsg_multiline("lua_error", "Lua callback:\n%s", error); 202 break; 203 case kThread: 204 semsg_multiline("lua_error", "Luv thread:\n%s", error); 205 break; 206 case kThreadCallback: 207 semsg_multiline("lua_error", "Luv callback, thread:\n%s", error); 208 break; 209 default: 210 break; 211 } 212 xfree(error); 213 } 214 215 /// Execute callback in "fast" context. Used for luv and some vim.ui_event 216 /// callbacks where using the API directly is not safe. 217 static int nlua_fast_cfpcall(lua_State *lstate, int nargs, int nresult, int flags) 218 FUNC_ATTR_NONNULL_ALL 219 { 220 int retval; 221 222 in_fast_callback++; 223 224 int top = lua_gettop(lstate); 225 int status = nlua_pcall(lstate, nargs, nresult); 226 if (status) { 227 if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) { 228 // consider out of memory errors unrecoverable, just like xmalloc() 229 preserve_exit(e_outofmem); 230 } 231 232 size_t len; 233 const char *error = nlua_get_error(lstate, &len); 234 235 multiqueue_put(main_loop.events, nlua_luv_error_event, 236 error != NULL ? xstrdup(error) : NULL, (void *)(intptr_t)kCallback); 237 lua_pop(lstate, 1); // error message 238 retval = -status; 239 } else { // LUA_OK 240 if (nresult == LUA_MULTRET) { 241 nresult = lua_gettop(lstate) - top + nargs + 1; 242 } 243 retval = nresult; 244 } 245 246 in_fast_callback--; 247 return retval; 248 } 249 250 static int nlua_luv_thread_cb_cfpcall(lua_State *lstate, int nargs, int nresult, int flags) 251 { 252 return nlua_luv_thread_common_cfpcall(lstate, nargs, nresult, flags, true); 253 } 254 255 static int nlua_luv_thread_cfpcall(lua_State *lstate, int nargs, int nresult, int flags) 256 FUNC_ATTR_NONNULL_ALL 257 { 258 return nlua_luv_thread_common_cfpcall(lstate, nargs, nresult, flags, false); 259 } 260 261 static int nlua_luv_thread_cfcpcall(lua_State *lstate, lua_CFunction func, void *ud, int flags) 262 FUNC_ATTR_NONNULL_ARG(1, 2) 263 { 264 lua_pushcfunction(lstate, func); 265 lua_pushlightuserdata(lstate, ud); 266 int retval = nlua_luv_thread_cfpcall(lstate, 1, 0, flags); 267 return retval; 268 } 269 270 static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nresult, int flags, 271 bool is_callback) 272 FUNC_ATTR_NONNULL_ALL 273 { 274 int retval; 275 276 int top = lua_gettop(lstate); 277 int status = lua_pcall(lstate, nargs, nresult, 0); 278 if (status) { 279 if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) { 280 // Terminate this thread, as the main thread may be able to continue 281 // execution. 282 fprintf(stderr, "%s\n", e_outofmem); 283 lua_close(lstate); 284 #ifdef MSWIN 285 ExitThread(0); 286 #else 287 pthread_exit(0); 288 #endif 289 } 290 const char *error = lua_tostring(lstate, -1); 291 loop_schedule_deferred(&main_loop, 292 event_create(nlua_luv_error_event, 293 error != NULL ? xstrdup(error) : NULL, 294 (void *)(intptr_t)(is_callback 295 ? kThreadCallback 296 : kThread))); 297 lua_pop(lstate, 1); // error message 298 retval = -status; 299 } else { // LUA_OK 300 if (nresult == LUA_MULTRET) { 301 nresult = lua_gettop(lstate) - top + nargs + 1; 302 } 303 retval = nresult; 304 } 305 306 return retval; 307 } 308 309 static int nlua_thr_api_nvim__get_runtime(lua_State *lstate) 310 { 311 if (lua_gettop(lstate) != 3) { 312 return luaL_error(lstate, "Expected 3 arguments"); 313 } 314 315 luaL_checktype(lstate, -1, LUA_TTABLE); 316 lua_getfield(lstate, -1, "is_lua"); 317 if (!lua_isboolean(lstate, -1)) { 318 return luaL_error(lstate, "is_lua is not a boolean"); 319 } 320 bool is_lua = lua_toboolean(lstate, -1); 321 lua_pop(lstate, 2); 322 323 luaL_checktype(lstate, -1, LUA_TBOOLEAN); 324 bool all = lua_toboolean(lstate, -1); 325 lua_pop(lstate, 1); 326 327 Error err = ERROR_INIT; 328 // TODO(bfredl): we could use an arena here for both "pat" and "ret", but then 329 // we need a path to not use the freelist but a private block local to the thread. 330 // We do not want mutex contentionery for the main arena freelist. 331 const Array pat = nlua_pop_Array(lstate, NULL, &err); 332 if (ERROR_SET(&err)) { 333 luaL_where(lstate, 1); 334 lua_pushstring(lstate, err.msg); 335 api_clear_error(&err); 336 lua_concat(lstate, 2); 337 return lua_error(lstate); 338 } 339 340 ArrayOf(String) ret = runtime_get_named_thread(is_lua, pat, all); 341 nlua_push_Array(lstate, ret, kNluaPushSpecial); 342 api_free_array(ret); 343 api_free_array(pat); 344 345 return 1; 346 } 347 348 /// Copies args starting at `lua_arg0` to Lua `_G.arg`, and sets `_G.arg[0]` to the scriptname. 349 /// 350 /// Example (arg[0] => "foo.lua", arg[1] => "--arg1", …): 351 /// nvim -l foo.lua --arg1 --arg2 352 /// 353 /// @note Lua CLI sets args before "-e" as _negative_ `_G.arg` indices, but we currently don't. 354 /// 355 /// @see https://www.lua.org/pil/1.4.html 356 /// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594 357 /// 358 /// @returns number of args 359 static int nlua_init_argv(lua_State *const L, char **argv, int argc, int lua_arg0) 360 { 361 int i = 0; 362 lua_newtable(L); // _G.arg 363 364 if (lua_arg0 > 0) { 365 lua_pushstring(L, argv[lua_arg0 - 1]); 366 lua_rawseti(L, -2, 0); // _G.arg[0] = "foo.lua" 367 368 for (; i + lua_arg0 < argc; i++) { 369 lua_pushstring(L, argv[i + lua_arg0]); 370 lua_rawseti(L, -2, i + 1); // _G.arg[i+1] = "--foo" 371 } 372 } 373 374 lua_setglobal(L, "arg"); 375 return i; 376 } 377 378 static void nlua_schedule_event(void **argv) 379 { 380 LuaRef cb = (LuaRef)(ptrdiff_t)argv[0]; 381 uint32_t ns_id = (uint32_t)(ptrdiff_t)argv[1]; 382 lua_State *const lstate = global_lstate; 383 nlua_pushref(lstate, cb); 384 nlua_unref_global(lstate, cb); 385 386 // Don't impose textlock restrictions upon UI event handlers. 387 int save_expr_map_lock = expr_map_lock; 388 int save_textlock = textlock; 389 expr_map_lock = ns_id > 0 ? 0 : expr_map_lock; 390 textlock = ns_id > 0 ? 0 : textlock; 391 if (nlua_pcall(lstate, 0, 0)) { 392 nlua_error(lstate, _("vim.schedule callback: %.*s")); 393 ui_remove_cb(ns_id, true); 394 } 395 expr_map_lock = save_expr_map_lock; 396 textlock = save_textlock; 397 } 398 399 /// Schedule Lua callback on main loop's event queue 400 /// 401 /// @param lstate Lua interpreter state. 402 static int nlua_schedule(lua_State *const lstate) 403 FUNC_ATTR_NONNULL_ALL 404 { 405 if (lua_type(lstate, 1) != LUA_TFUNCTION) { 406 lua_pushliteral(lstate, "vim.schedule: expected function"); 407 return lua_error(lstate); 408 } 409 410 lua_pushnil(lstate); 411 // If main_loop is closing don't schedule tasks to run in the future, 412 // otherwise any refs allocated here will not be cleaned up. 413 if (main_loop.closing) { 414 lua_pushliteral(lstate, "main loop is closing"); 415 return 2; 416 } 417 418 LuaRef cb = nlua_ref_global(lstate, 1); 419 // Pass along UI event handler to disable on error. 420 multiqueue_put(main_loop.events, nlua_schedule_event, (void *)(ptrdiff_t)cb, 421 (void *)(ptrdiff_t)ui_event_ns_id); 422 lua_pushnil(lstate); 423 return 2; 424 } 425 426 // Dummy timer callback. Used by vim.wait(). 427 static void dummy_timer_due_cb(TimeWatcher *tw, void *data) 428 { 429 // If the main loop is closing, the condition won't be checked again. 430 // Close the timer to avoid leaking resources. 431 if (main_loop.closing) { 432 time_watcher_stop(tw); 433 time_watcher_close(tw, dummy_timer_close_cb); 434 } 435 } 436 437 // Dummy timer close callback. Used by vim.wait(). 438 static void dummy_timer_close_cb(TimeWatcher *tw, void *data) 439 { 440 xfree(tw); 441 } 442 443 static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_result, 444 int *nresults) 445 { 446 int top = lua_gettop(lstate); 447 lua_pushvalue(lstate, 2); 448 *status = nlua_pcall(lstate, 0, LUA_MULTRET); 449 if (*status) { 450 return true; // break on error, but keep error on stack 451 } 452 *nresults = lua_gettop(lstate) - top; 453 if (*nresults == 0) { 454 *callback_result = false; 455 return false; 456 } 457 *callback_result = lua_toboolean(lstate, top + 1); 458 if (!*callback_result) { 459 lua_settop(lstate, top); 460 return false; 461 } 462 lua_remove(lstate, top + 1); 463 (*nresults)--; 464 return true; // break if true 465 } 466 467 /// "vim.wait(timeout, condition[, interval])" function 468 static int nlua_wait(lua_State *lstate) 469 FUNC_ATTR_NONNULL_ALL 470 { 471 if (in_fast_callback) { 472 return luaL_error(lstate, e_fast_api_disabled, "vim.wait"); 473 } 474 475 double timeout_number = luaL_checknumber(lstate, 1); 476 if (timeout_number < 0) { 477 return luaL_error(lstate, "timeout must be >= 0"); 478 } 479 int64_t timeout = (isnan(timeout_number) || timeout_number > (double)INT64_MAX) 480 ? INT64_MAX 481 : (int64_t)timeout_number; 482 483 int lua_top = lua_gettop(lstate); 484 485 // Check if condition can be called. 486 bool is_function = false; 487 if (lua_top >= 2 && !lua_isnil(lstate, 2)) { 488 is_function = (lua_type(lstate, 2) == LUA_TFUNCTION); 489 490 // Check if condition is callable table 491 if (!is_function && luaL_getmetafield(lstate, 2, "__call") != 0) { 492 is_function = (lua_type(lstate, -1) == LUA_TFUNCTION); 493 lua_pop(lstate, 1); 494 } 495 496 if (!is_function) { 497 lua_pushliteral(lstate, "vim.wait: callback must be callable"); 498 return lua_error(lstate); 499 } 500 } 501 502 intptr_t interval = 200; 503 if (lua_top >= 3 && !lua_isnil(lstate, 3)) { 504 interval = luaL_checkinteger(lstate, 3); 505 if (interval < 0) { 506 return luaL_error(lstate, "interval must be >= 0"); 507 } 508 } 509 510 bool fast_only = false; 511 if (lua_top >= 4) { 512 fast_only = lua_toboolean(lstate, 4); 513 } 514 515 MultiQueue *loop_events = fast_only ? main_loop.fast_events : main_loop.events; 516 517 TimeWatcher *tw = xmalloc(sizeof(TimeWatcher)); 518 519 // Start dummy timer. 520 time_watcher_init(&main_loop, tw, NULL); 521 // Don't schedule the due callback, as that'll lead to two different types of events 522 // on each interval, causing the condition to be checked twice. 523 tw->events = NULL; 524 time_watcher_start(tw, dummy_timer_due_cb, (uint64_t)interval, (uint64_t)interval); 525 526 int pcall_status = 0; 527 bool callback_result = false; 528 int nresults = 0; 529 530 // Flush screen updates before blocking. 531 ui_flush(); 532 533 LOOP_PROCESS_EVENTS_UNTIL(&main_loop, 534 loop_events, 535 timeout, 536 got_int || (is_function ? nlua_wait_condition(lstate, 537 &pcall_status, 538 &callback_result, 539 &nresults) 540 : false)); 541 542 // Stop dummy timer 543 time_watcher_stop(tw); 544 time_watcher_close(tw, dummy_timer_close_cb); 545 546 if (pcall_status) { 547 return lua_error(lstate); 548 } else if (callback_result) { 549 lua_pushboolean(lstate, 1); 550 if (nresults == 0) { 551 lua_pushnil(lstate); 552 nresults = 1; 553 } else { 554 lua_insert(lstate, -1 - nresults); 555 } 556 return nresults + 1; 557 } else if (got_int) { 558 got_int = false; 559 vgetc(); 560 lua_pushboolean(lstate, 0); 561 lua_pushinteger(lstate, -2); 562 return 2; 563 } else { 564 lua_pushboolean(lstate, 0); 565 lua_pushinteger(lstate, -1); 566 return 2; 567 } 568 } 569 570 static nlua_ref_state_t *nlua_new_ref_state(lua_State *lstate, bool is_thread) 571 FUNC_ATTR_NONNULL_ALL 572 { 573 nlua_ref_state_t *ref_state = lua_newuserdata(lstate, sizeof(*ref_state)); 574 CLEAR_POINTER(ref_state); 575 ref_state->nil_ref = LUA_NOREF; 576 ref_state->empty_dict_ref = LUA_NOREF; 577 if (!is_thread) { 578 nlua_global_refs = ref_state; 579 } 580 return ref_state; 581 } 582 583 static nlua_ref_state_t *nlua_get_ref_state(lua_State *lstate) 584 FUNC_ATTR_NONNULL_ALL 585 { 586 lua_getfield(lstate, LUA_REGISTRYINDEX, "nlua.ref_state"); 587 nlua_ref_state_t *ref_state = lua_touserdata(lstate, -1); 588 lua_pop(lstate, 1); 589 590 return ref_state; 591 } 592 593 LuaRef nlua_get_nil_ref(lua_State *lstate) 594 FUNC_ATTR_NONNULL_ALL 595 { 596 nlua_ref_state_t *ref_state = nlua_get_ref_state(lstate); 597 return ref_state->nil_ref; 598 } 599 600 LuaRef nlua_get_empty_dict_ref(lua_State *lstate) 601 FUNC_ATTR_NONNULL_ALL 602 { 603 nlua_ref_state_t *ref_state = nlua_get_ref_state(lstate); 604 return ref_state->empty_dict_ref; 605 } 606 607 int nlua_get_global_ref_count(void) 608 { 609 return nlua_global_refs->ref_count; 610 } 611 612 static void nlua_common_vim_init(lua_State *lstate, bool is_thread, bool is_standalone) 613 FUNC_ATTR_NONNULL_ARG(1) 614 { 615 nlua_ref_state_t *ref_state = nlua_new_ref_state(lstate, is_thread); 616 lua_setfield(lstate, LUA_REGISTRYINDEX, "nlua.ref_state"); 617 618 // vim.is_thread 619 lua_pushboolean(lstate, is_thread); 620 lua_setfield(lstate, LUA_REGISTRYINDEX, "nvim.thread"); 621 lua_pushcfunction(lstate, &nlua_is_thread); 622 lua_setfield(lstate, -2, "is_thread"); 623 624 // vim.NIL 625 lua_newuserdata(lstate, 0); 626 lua_createtable(lstate, 0, 0); 627 lua_pushcfunction(lstate, &nlua_nil_tostring); 628 lua_setfield(lstate, -2, "__tostring"); 629 lua_setmetatable(lstate, -2); 630 ref_state->nil_ref = nlua_ref(lstate, ref_state, -1); 631 lua_pushvalue(lstate, -1); 632 lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.NIL"); 633 lua_setfield(lstate, -2, "NIL"); 634 635 // vim._empty_dict_mt 636 lua_createtable(lstate, 0, 0); 637 lua_pushcfunction(lstate, &nlua_empty_dict_tostring); 638 lua_setfield(lstate, -2, "__tostring"); 639 ref_state->empty_dict_ref = nlua_ref(lstate, ref_state, -1); 640 lua_pushvalue(lstate, -1); 641 lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.empty_dict"); 642 lua_setfield(lstate, -2, "_empty_dict_mt"); 643 644 // vim.uv 645 if (is_standalone) { 646 // do nothing, use libluv like in a standalone interpreter 647 } else if (is_thread) { 648 luv_set_callback(lstate, nlua_luv_thread_cb_cfpcall); 649 luv_set_thread(lstate, nlua_luv_thread_cfpcall); 650 luv_set_cthread(lstate, nlua_luv_thread_cfcpcall); 651 } else { 652 luv_set_loop(lstate, &main_loop.uv); 653 luv_set_callback(lstate, nlua_fast_cfpcall); 654 } 655 luaopen_luv(lstate); 656 lua_pushvalue(lstate, -1); 657 lua_setfield(lstate, -3, "uv"); 658 659 lua_pushvalue(lstate, -1); 660 lua_setfield(lstate, -3, "loop"); // deprecated 661 662 // package.loaded.luv = vim.uv 663 // otherwise luv will be reinitialized when require'luv' 664 lua_getglobal(lstate, "package"); 665 lua_getfield(lstate, -1, "loaded"); 666 lua_pushvalue(lstate, -3); 667 lua_setfield(lstate, -2, "luv"); 668 lua_pop(lstate, 3); 669 } 670 671 static int nlua_module_preloader(lua_State *lstate) 672 { 673 size_t i = (size_t)lua_tointeger(lstate, lua_upvalueindex(1)); 674 ModuleDef def = builtin_modules[i]; 675 char name[256]; 676 name[0] = '@'; 677 size_t off = xstrlcpy(name + 1, def.name, (sizeof name) - 2); 678 strchrsub(name + 1, '.', '/'); 679 xstrlcpy(name + 1 + off, ".lua", (sizeof name) - 2 - off); 680 681 if (luaL_loadbuffer(lstate, (const char *)def.data, def.size - 1, name)) { 682 return lua_error(lstate); 683 } 684 685 lua_call(lstate, 0, 1); // propagates error to caller 686 return 1; 687 } 688 689 static bool nlua_init_packages(lua_State *lstate, bool is_standalone) 690 FUNC_ATTR_NONNULL_ALL 691 { 692 // put builtin packages in preload 693 lua_getglobal(lstate, "package"); // [package] 694 lua_getfield(lstate, -1, "preload"); // [package, preload] 695 for (size_t i = 0; i < ARRAY_SIZE(builtin_modules); i++) { 696 ModuleDef def = builtin_modules[i]; 697 lua_pushinteger(lstate, (lua_Integer)i); // [package, preload, i] 698 lua_pushcclosure(lstate, nlua_module_preloader, 1); // [package, preload, cclosure] 699 lua_setfield(lstate, -2, def.name); // [package, preload] 700 701 if ((nlua_disable_preload && !is_standalone) && strequal(def.name, "vim.inspect")) { 702 break; 703 } 704 } 705 706 lua_pop(lstate, 2); // [] 707 708 lua_getglobal(lstate, "require"); 709 lua_pushstring(lstate, "vim._init_packages"); 710 if (nlua_pcall(lstate, 1, 0)) { 711 fprintf(stderr, "%s\n", lua_tostring(lstate, -1)); 712 return false; 713 } 714 715 return true; 716 } 717 718 /// "vim.ui_attach(ns_id, {ext_foo=true}, cb)" function 719 static int nlua_ui_attach(lua_State *lstate) 720 FUNC_ATTR_NONNULL_ALL 721 { 722 uint32_t ns_id = (uint32_t)luaL_checkinteger(lstate, 1); 723 724 if (!ns_initialized(ns_id)) { 725 return luaL_error(lstate, "invalid ns_id"); 726 } 727 if (!lua_istable(lstate, 2)) { 728 return luaL_error(lstate, "opts must be a table"); 729 } 730 if (!lua_isfunction(lstate, 3)) { 731 return luaL_error(lstate, "callback must be a Lua function"); 732 } 733 734 bool ext_widgets[kUIGlobalCount] = { false }; 735 bool tbl_has_true_val = false; 736 737 lua_pushvalue(lstate, 2); 738 lua_pushnil(lstate); 739 while (lua_next(lstate, -2)) { 740 // [dict, key, val] 741 size_t len; 742 const char *s = lua_tolstring(lstate, -2, &len); 743 bool val = lua_toboolean(lstate, -1); 744 745 if (strequal(s, "set_cmdheight")) { 746 ui_refresh_cmdheight = val; 747 goto ok; 748 } else { 749 for (size_t i = 0; i < kUIGlobalCount; i++) { 750 if (strequal(s, ui_ext_names[i])) { 751 if (val) { 752 tbl_has_true_val = true; 753 } 754 ext_widgets[i] = val; 755 goto ok; 756 } 757 } 758 } 759 760 return luaL_error(lstate, "Unexpected key: %s", s); 761 ok: 762 lua_pop(lstate, 1); 763 } 764 765 if (!tbl_has_true_val) { 766 return luaL_error(lstate, "opts table must contain at least one 'true' ext_widget"); 767 } 768 769 LuaRef ui_event_cb = nlua_ref_global(lstate, 3); 770 ui_add_cb(ns_id, ui_event_cb, ext_widgets); 771 ui_refresh_cmdheight = true; 772 return 0; 773 } 774 775 /// "vim.ui_detach(ns_id)" function 776 static int nlua_ui_detach(lua_State *lstate) 777 FUNC_ATTR_NONNULL_ALL 778 { 779 uint32_t ns_id = (uint32_t)luaL_checkinteger(lstate, 1); 780 781 if (!ns_initialized(ns_id)) { 782 return luaL_error(lstate, "invalid ns_id"); 783 } 784 785 ui_remove_cb(ns_id, false); 786 return 0; 787 } 788 789 /// Initialize lua interpreter state 790 /// 791 /// Called by lua interpreter itself to initialize state. 792 static bool nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL 793 { 794 // print 795 lua_pushcfunction(lstate, &nlua_print); 796 lua_setglobal(lstate, "print"); 797 798 // debug.debug 799 lua_getglobal(lstate, "debug"); 800 lua_pushcfunction(lstate, &nlua_debug); 801 lua_setfield(lstate, -2, "debug"); 802 lua_pop(lstate, 1); 803 804 #ifdef MSWIN 805 // os.getenv 806 lua_getglobal(lstate, "os"); 807 lua_pushcfunction(lstate, &nlua_getenv); 808 lua_setfield(lstate, -2, "getenv"); 809 lua_pop(lstate, 1); 810 #endif 811 812 // vim 813 lua_newtable(lstate); 814 815 // vim.api 816 nlua_add_api_functions(lstate); 817 818 // vim.types, vim.type_idx, vim.val_idx 819 nlua_init_types(lstate); 820 821 // schedule 822 lua_pushcfunction(lstate, &nlua_schedule); 823 lua_setfield(lstate, -2, "schedule"); 824 825 // in_fast_event 826 lua_pushcfunction(lstate, &nlua_in_fast_event); 827 lua_setfield(lstate, -2, "in_fast_event"); 828 829 // call 830 lua_pushcfunction(lstate, &nlua_call); 831 lua_setfield(lstate, -2, "call"); 832 833 // rpcrequest 834 lua_pushcfunction(lstate, &nlua_rpcrequest); 835 lua_setfield(lstate, -2, "rpcrequest"); 836 837 // rpcnotify 838 lua_pushcfunction(lstate, &nlua_rpcnotify); 839 lua_setfield(lstate, -2, "rpcnotify"); 840 841 // wait 842 lua_pushcfunction(lstate, &nlua_wait); 843 lua_setfield(lstate, -2, "wait"); 844 845 // ui_attach 846 lua_pushcfunction(lstate, &nlua_ui_attach); 847 lua_setfield(lstate, -2, "ui_attach"); 848 849 // ui_detach 850 lua_pushcfunction(lstate, &nlua_ui_detach); 851 lua_setfield(lstate, -2, "ui_detach"); 852 853 nlua_common_vim_init(lstate, false, false); 854 855 // patch require() (only for --startuptime) 856 if (time_fd != NULL) { 857 lua_getglobal(lstate, "require"); 858 // Must do this after nlua_common_vim_init where nlua_global_refs is initialized. 859 require_ref = nlua_ref_global(lstate, -1); 860 lua_pop(lstate, 1); 861 lua_pushcfunction(lstate, &nlua_require); 862 lua_setglobal(lstate, "require"); 863 } 864 865 // internal vim._treesitter... API 866 nlua_treesitter_init(lstate); 867 868 nlua_state_add_stdlib(lstate, false); 869 870 lua_setglobal(lstate, "vim"); 871 872 if (!nlua_init_packages(lstate, false)) { 873 return false; 874 } 875 876 return true; 877 } 878 879 /// Initializes global Lua interpreter, or exits Nvim on failure. 880 void nlua_init(char **argv, int argc, int lua_arg0) 881 { 882 #ifdef NLUA_TRACK_REFS 883 if (os_env_exists("NVIM_LUA_NOTRACK", true)) { 884 nlua_track_refs = true; 885 } 886 #endif 887 888 lua_State *lstate = luaL_newstate(); 889 if (lstate == NULL) { 890 fprintf(stderr, _("E970: Failed to initialize lua interpreter\n")); 891 os_exit(1); 892 } 893 luaL_openlibs(lstate); 894 if (!nlua_state_init(lstate)) { 895 fprintf(stderr, _("E970: Failed to initialize builtin lua modules\n")); 896 #ifdef EXITFREE 897 nlua_common_free_all_mem(lstate); 898 #endif 899 os_exit(1); 900 } 901 902 luv_set_thread_cb(nlua_thread_acquire_vm, nlua_common_free_all_mem); 903 global_lstate = lstate; 904 active_lstate = lstate; 905 main_thread = uv_thread_self(); 906 nlua_init_argv(lstate, argv, argc, lua_arg0); 907 } 908 909 static lua_State *nlua_thread_acquire_vm(void) 910 { 911 return nlua_init_state(true); 912 } 913 914 void nlua_run_script(char **argv, int argc, int lua_arg0) 915 FUNC_ATTR_NORETURN 916 { 917 in_script = true; 918 global_lstate = nlua_init_state(false); 919 luv_set_thread_cb(nlua_thread_acquire_vm, nlua_common_free_all_mem); 920 nlua_init_argv(global_lstate, argv, argc, lua_arg0); 921 bool lua_ok = nlua_exec_file(argv[lua_arg0 - 1]); 922 #ifdef EXITFREE 923 nlua_free_all_mem(); 924 #endif 925 exit(lua_ok ? 0 : 1); 926 } 927 928 static lua_State *nlua_init_state(bool thread) 929 { 930 // If it is called from the main thread, it will attempt to rebuild the cache. 931 const uv_thread_t self = uv_thread_self(); 932 if (!in_script && uv_thread_equal(&main_thread, &self)) { 933 runtime_search_path_validate(); 934 } 935 936 lua_State *lstate = luaL_newstate(); 937 938 // Add in the lua standard libraries 939 luaL_openlibs(lstate); 940 941 if (!in_script) { 942 // print 943 lua_pushcfunction(lstate, &nlua_print); 944 lua_setglobal(lstate, "print"); 945 } 946 947 lua_pushinteger(lstate, 0); 948 lua_setfield(lstate, LUA_REGISTRYINDEX, "nlua.refcount"); 949 950 // vim 951 lua_newtable(lstate); 952 953 nlua_common_vim_init(lstate, thread, in_script); 954 955 nlua_state_add_stdlib(lstate, true); 956 957 if (!in_script) { 958 lua_createtable(lstate, 0, 0); 959 lua_pushcfunction(lstate, nlua_thr_api_nvim__get_runtime); 960 lua_setfield(lstate, -2, "nvim__get_runtime"); 961 lua_setfield(lstate, -2, "api"); 962 } 963 964 lua_setglobal(lstate, "vim"); 965 966 nlua_init_packages(lstate, in_script); 967 968 lua_getglobal(lstate, "package"); 969 lua_getfield(lstate, -1, "loaded"); 970 lua_getglobal(lstate, "vim"); 971 lua_setfield(lstate, -2, "vim"); 972 lua_pop(lstate, 2); 973 974 return lstate; 975 } 976 977 void nlua_free_all_mem(void) 978 { 979 if (!global_lstate) { 980 return; 981 } 982 lua_State *lstate = global_lstate; 983 nlua_unref_global(lstate, require_ref); 984 nlua_common_free_all_mem(lstate); 985 nlua_treesitter_free(); 986 } 987 988 static void nlua_common_free_all_mem(lua_State *lstate) 989 FUNC_ATTR_NONNULL_ALL 990 { 991 nlua_ref_state_t *ref_state = nlua_get_ref_state(lstate); 992 nlua_unref(lstate, ref_state, ref_state->nil_ref); 993 nlua_unref(lstate, ref_state, ref_state->empty_dict_ref); 994 995 #ifdef NLUA_TRACK_REFS 996 if (ref_state->ref_count) { 997 fprintf(stderr, "%d lua references were leaked!", ref_state->ref_count); 998 } 999 1000 if (nlua_track_refs) { 1001 // in case there are leaked luarefs, leak the associated memory 1002 // to get LeakSanitizer stacktraces on exit 1003 map_destroy(int, &ref_state->ref_markers); 1004 } 1005 #endif 1006 1007 lua_close(lstate); 1008 } 1009 1010 static void nlua_print_event(void **argv) 1011 { 1012 HlMessage msg = KV_INITIAL_VALUE; 1013 HlMessageChunk chunk = { { .data = argv[0], .size = (size_t)(intptr_t)argv[1] - 1 }, 0 }; 1014 kv_push(msg, chunk); 1015 bool needs_clear = false; 1016 msg_multihl(INTEGER_OBJ(0), msg, "lua_print", true, false, NULL, &needs_clear); 1017 } 1018 1019 /// Print as a Vim message 1020 /// 1021 /// @param lstate Lua interpreter state. 1022 static int nlua_print(lua_State *const lstate) 1023 FUNC_ATTR_NONNULL_ALL 1024 { 1025 #define PRINT_ERROR(msg) \ 1026 do { \ 1027 errmsg = msg; \ 1028 errmsg_len = sizeof(msg) - 1; \ 1029 goto nlua_print_error; \ 1030 } while (0) 1031 const int nargs = lua_gettop(lstate); 1032 lua_getglobal(lstate, "tostring"); 1033 const char *errmsg = NULL; 1034 size_t errmsg_len = 0; 1035 garray_T msg_ga; 1036 ga_init(&msg_ga, 1, 80); 1037 int curargidx = 1; 1038 for (; curargidx <= nargs; curargidx++) { 1039 lua_pushvalue(lstate, -1); // tostring 1040 lua_pushvalue(lstate, curargidx); // arg 1041 // Do not use nlua_pcall here to avoid duplicate stack trace information 1042 if (lua_pcall(lstate, 1, 1, 0)) { 1043 errmsg = lua_tolstring(lstate, -1, &errmsg_len); 1044 goto nlua_print_error; 1045 } 1046 size_t len; 1047 const char *const s = lua_tolstring(lstate, -1, &len); 1048 if (s == NULL) { 1049 PRINT_ERROR("<Unknown error: lua_tolstring returned NULL for tostring result>"); 1050 } 1051 ga_concat_len(&msg_ga, s, len); 1052 if (curargidx < nargs) { 1053 ga_append(&msg_ga, ' '); 1054 } 1055 lua_pop(lstate, 1); 1056 } 1057 #undef PRINT_ERROR 1058 ga_append(&msg_ga, NUL); 1059 1060 lua_getfield(lstate, LUA_REGISTRYINDEX, "nvim.thread"); 1061 bool is_thread = lua_toboolean(lstate, -1); 1062 lua_pop(lstate, 1); 1063 1064 if (is_thread) { 1065 loop_schedule_deferred(&main_loop, 1066 event_create(nlua_print_event, 1067 msg_ga.ga_data, 1068 (void *)(intptr_t)msg_ga.ga_len)); 1069 } else if (in_fast_callback) { 1070 multiqueue_put(main_loop.events, nlua_print_event, 1071 msg_ga.ga_data, (void *)(intptr_t)msg_ga.ga_len); 1072 } else { 1073 nlua_print_event((void *[]){ msg_ga.ga_data, (void *)(intptr_t)msg_ga.ga_len }); 1074 } 1075 return 0; 1076 1077 nlua_print_error: 1078 ga_clear(&msg_ga); 1079 char *buff = xmalloc(IOSIZE); 1080 const char *fmt = _("E5114: Converting print argument #%i: %.*s"); 1081 size_t len = (size_t)vim_snprintf(buff, IOSIZE, fmt, curargidx, 1082 (int)errmsg_len, errmsg); 1083 lua_pushlstring(lstate, buff, len); 1084 xfree(buff); 1085 return lua_error(lstate); 1086 } 1087 1088 /// require() for --startuptime 1089 /// 1090 /// @param lstate Lua interpreter state. 1091 static int nlua_require(lua_State *const lstate) 1092 FUNC_ATTR_NONNULL_ALL 1093 { 1094 const char *name = luaL_checkstring(lstate, 1); 1095 lua_settop(lstate, 1); 1096 // [ name ] 1097 1098 // try cached module from package.loaded first 1099 lua_getfield(lstate, LUA_REGISTRYINDEX, "_LOADED"); 1100 lua_getfield(lstate, 2, name); 1101 // [ name package.loaded module ] 1102 if (lua_toboolean(lstate, -1)) { 1103 return 1; 1104 } 1105 lua_pop(lstate, 2); 1106 // [ name ] 1107 1108 // push original require below the module name 1109 nlua_pushref(lstate, require_ref); 1110 lua_insert(lstate, 1); 1111 // [ require name ] 1112 1113 if (time_fd == NULL) { 1114 // after log file was closed, try to restore 1115 // global require to the original function... 1116 lua_getglobal(lstate, "require"); 1117 // ...only if it's still referencing this wrapper, 1118 // to not overwrite it in case someone happened to 1119 // patch it in the meantime... 1120 if (lua_iscfunction(lstate, -1) && lua_tocfunction(lstate, -1) == nlua_require) { 1121 lua_pushvalue(lstate, 1); 1122 lua_setglobal(lstate, "require"); 1123 } 1124 lua_pop(lstate, 1); 1125 1126 // ...and then call require directly. 1127 lua_call(lstate, 1, 1); 1128 return 1; 1129 } 1130 1131 proftime_T rel_time; 1132 proftime_T start_time; 1133 time_push(&rel_time, &start_time); 1134 int status = lua_pcall(lstate, 1, 1, 0); 1135 if (status == 0) { 1136 vim_snprintf(IObuff, IOSIZE, "require('%s')", name); 1137 time_msg(IObuff, &start_time); 1138 } 1139 time_pop(rel_time); 1140 1141 return status == 0 ? 1 : lua_error(lstate); 1142 } 1143 1144 /// debug.debug: interaction with user while debugging. 1145 /// 1146 /// @param lstate Lua interpreter state. 1147 static int nlua_debug(lua_State *lstate) 1148 FUNC_ATTR_NONNULL_ALL 1149 { 1150 const typval_T input_args[] = { 1151 { 1152 .v_lock = VAR_FIXED, 1153 .v_type = VAR_STRING, 1154 .vval.v_string = "lua_debug> ", 1155 }, 1156 { 1157 .v_type = VAR_UNKNOWN, 1158 }, 1159 }; 1160 while (true) { 1161 lua_settop(lstate, 0); 1162 typval_T input; 1163 get_user_input(input_args, &input, false, false); 1164 msg_putchar('\n'); // Avoid outputting on input line. 1165 if (input.v_type != VAR_STRING 1166 || input.vval.v_string == NULL 1167 || *input.vval.v_string == NUL 1168 || strcmp(input.vval.v_string, "cont") == 0) { 1169 tv_clear(&input); 1170 return 0; 1171 } 1172 if (luaL_loadbuffer(lstate, input.vval.v_string, 1173 strlen(input.vval.v_string), "=(debug command)")) { 1174 nlua_error(lstate, _("E5115: Loading Lua debug string: %.*s")); 1175 } else if (nlua_pcall(lstate, 0, 0)) { 1176 nlua_error(lstate, _("E5116: Calling Lua debug string: %.*s")); 1177 } 1178 tv_clear(&input); 1179 } 1180 return 0; 1181 } 1182 1183 int nlua_in_fast_event(lua_State *lstate) 1184 { 1185 lua_pushboolean(lstate, in_fast_callback > 0); 1186 return 1; 1187 } 1188 1189 static bool viml_func_is_fast(const char *name) 1190 { 1191 const EvalFuncDef *const fdef = find_internal_func(name); 1192 if (fdef) { 1193 return fdef->fast; 1194 } 1195 // Not a Vimscript function 1196 return false; 1197 } 1198 1199 int nlua_call(lua_State *lstate) 1200 { 1201 Error err = ERROR_INIT; 1202 size_t name_len; 1203 const char *name = luaL_checklstring(lstate, 1, &name_len); 1204 if (!nlua_is_deferred_safe() && !viml_func_is_fast(name)) { 1205 size_t length = MIN(strlen(name), 100) + sizeof("Vimscript function \"\""); 1206 vim_snprintf(IObuff, length, "Vimscript function \"%s\"", name); 1207 int ret = luaL_error(lstate, e_fast_api_disabled, IObuff); 1208 return ret; 1209 } 1210 1211 int nargs = lua_gettop(lstate) - 1; 1212 if (nargs > MAX_FUNC_ARGS) { 1213 return luaL_error(lstate, "Function called with too many arguments"); 1214 } 1215 1216 typval_T vim_args[MAX_FUNC_ARGS + 1]; 1217 int i = 0; // also used for freeing the variables 1218 for (; i < nargs; i++) { 1219 lua_pushvalue(lstate, i + 2); 1220 if (!nlua_pop_typval(lstate, &vim_args[i])) { 1221 api_set_error(&err, kErrorTypeException, 1222 "error converting argument %d", i + 1); 1223 goto free_vim_args; 1224 } 1225 } 1226 1227 // TODO(bfredl): this should be simplified in error handling refactor 1228 force_abort = false; 1229 suppress_errthrow = false; 1230 did_throw = false; 1231 did_emsg = false; 1232 1233 typval_T rettv; 1234 funcexe_T funcexe = FUNCEXE_INIT; 1235 funcexe.fe_firstline = curwin->w_cursor.lnum; 1236 funcexe.fe_lastline = curwin->w_cursor.lnum; 1237 funcexe.fe_evaluate = true; 1238 1239 TRY_WRAP(&err, { 1240 // call_func() retval is deceptive, ignore it. Instead we set `msg_list` 1241 // (TRY_WRAP) to capture abort-causing non-exception errors. 1242 (void)call_func(name, (int)name_len, &rettv, nargs, vim_args, &funcexe); 1243 }); 1244 1245 if (!ERROR_SET(&err)) { 1246 nlua_push_typval(lstate, &rettv, 0); 1247 } 1248 tv_clear(&rettv); 1249 1250 free_vim_args: 1251 while (i > 0) { 1252 tv_clear(&vim_args[--i]); 1253 } 1254 if (ERROR_SET(&err)) { 1255 lua_pushstring(lstate, err.msg); 1256 api_clear_error(&err); 1257 return lua_error(lstate); 1258 } 1259 return 1; 1260 } 1261 1262 static int nlua_rpcrequest(lua_State *lstate) 1263 { 1264 if (!nlua_is_deferred_safe()) { 1265 return luaL_error(lstate, e_fast_api_disabled, "rpcrequest"); 1266 } 1267 return nlua_rpc(lstate, true); 1268 } 1269 1270 static int nlua_rpcnotify(lua_State *lstate) 1271 { 1272 return nlua_rpc(lstate, false); 1273 } 1274 1275 static int nlua_rpc(lua_State *lstate, bool request) 1276 { 1277 size_t name_len; 1278 uint64_t chan_id = (uint64_t)luaL_checkinteger(lstate, 1); 1279 const char *name = luaL_checklstring(lstate, 2, &name_len); 1280 int nargs = lua_gettop(lstate) - 2; 1281 Error err = ERROR_INIT; 1282 Arena arena = ARENA_EMPTY; 1283 1284 Array args = arena_array(&arena, (size_t)nargs); 1285 for (int i = 0; i < nargs; i++) { 1286 lua_pushvalue(lstate, i + 3); 1287 ADD(args, nlua_pop_Object(lstate, false, &arena, &err)); 1288 if (ERROR_SET(&err)) { 1289 goto check_err; 1290 } 1291 } 1292 1293 if (request) { 1294 ArenaMem res_mem = NULL; 1295 Object result = rpc_send_call(chan_id, name, args, &res_mem, &err); 1296 if (!ERROR_SET(&err)) { 1297 nlua_push_Object(lstate, &result, 0); 1298 arena_mem_free(res_mem); 1299 } 1300 } else { 1301 if (!rpc_send_event(chan_id, name, args)) { 1302 api_set_error(&err, kErrorTypeValidation, 1303 "Invalid channel: %" PRIu64, chan_id); 1304 } 1305 } 1306 1307 check_err: 1308 arena_mem_free(arena_finish(&arena)); 1309 1310 if (ERROR_SET(&err)) { 1311 lua_pushstring(lstate, err.msg); 1312 api_clear_error(&err); 1313 return lua_error(lstate); 1314 } 1315 1316 return request ? 1 : 0; 1317 } 1318 1319 static int nlua_nil_tostring(lua_State *lstate) 1320 { 1321 lua_pushstring(lstate, "vim.NIL"); 1322 return 1; 1323 } 1324 1325 static int nlua_empty_dict_tostring(lua_State *lstate) 1326 { 1327 lua_pushstring(lstate, "vim.empty_dict()"); 1328 return 1; 1329 } 1330 1331 #ifdef MSWIN 1332 /// os.getenv: override os.getenv to maintain coherency. #9681 1333 /// 1334 /// uv_os_setenv uses SetEnvironmentVariableW which does not update _environ. 1335 /// 1336 /// @param lstate Lua interpreter state. 1337 static int nlua_getenv(lua_State *lstate) 1338 { 1339 lua_pushstring(lstate, os_getenv_noalloc(luaL_checkstring(lstate, 1))); 1340 return 1; 1341 } 1342 #endif 1343 1344 /// add the value to the registry 1345 /// The current implementation does not support calls from threads. 1346 LuaRef nlua_ref(lua_State *lstate, nlua_ref_state_t *ref_state, int index) 1347 { 1348 lua_pushvalue(lstate, index); 1349 LuaRef ref = luaL_ref(lstate, LUA_REGISTRYINDEX); 1350 if (ref > 0) { 1351 ref_state->ref_count++; 1352 #ifdef NLUA_TRACK_REFS 1353 if (nlua_track_refs) { 1354 // dummy allocation to make LeakSanitizer track our luarefs 1355 pmap_put(int)(&ref_state->ref_markers, ref, xmalloc(3)); 1356 } 1357 #endif 1358 } 1359 return ref; 1360 } 1361 1362 // TODO(lewis6991): Currently cannot be run in __gc metamethods as they are 1363 // invoked in lua_close() which can be invoked after the ref_markers map is 1364 // destroyed in nlua_common_free_all_mem. 1365 LuaRef nlua_ref_global(lua_State *lstate, int index) 1366 { 1367 return nlua_ref(lstate, nlua_global_refs, index); 1368 } 1369 1370 /// remove the value from the registry 1371 void nlua_unref(lua_State *lstate, nlua_ref_state_t *ref_state, LuaRef ref) 1372 { 1373 if (ref > 0) { 1374 ref_state->ref_count--; 1375 #ifdef NLUA_TRACK_REFS 1376 // NB: don't remove entry from map to track double-unref 1377 if (nlua_track_refs) { 1378 xfree(pmap_get(int)(&ref_state->ref_markers, ref)); 1379 } 1380 #endif 1381 luaL_unref(lstate, LUA_REGISTRYINDEX, ref); 1382 } 1383 } 1384 1385 void nlua_unref_global(lua_State *lstate, LuaRef ref) 1386 { 1387 nlua_unref(lstate, nlua_global_refs, ref); 1388 } 1389 1390 void api_free_luaref(LuaRef ref) 1391 { 1392 nlua_unref_global(global_lstate, ref); 1393 } 1394 1395 /// push a value referenced in the registry 1396 void nlua_pushref(lua_State *lstate, LuaRef ref) 1397 { 1398 lua_rawgeti(lstate, LUA_REGISTRYINDEX, ref); 1399 } 1400 1401 /// Gets a new reference to an object stored at original_ref 1402 /// 1403 /// NOTE: It does not copy the value, it creates a new ref to the lua object. 1404 /// Leaves the stack unchanged. 1405 LuaRef api_new_luaref(LuaRef original_ref) 1406 { 1407 if (original_ref == LUA_NOREF) { 1408 return LUA_NOREF; 1409 } 1410 1411 lua_State *const lstate = global_lstate; 1412 nlua_pushref(lstate, original_ref); 1413 LuaRef new_ref = nlua_ref_global(lstate, -1); 1414 lua_pop(lstate, 1); 1415 return new_ref; 1416 } 1417 1418 /// Evaluate lua string 1419 /// 1420 /// Used for luaeval(). 1421 /// 1422 /// @param[in] str String to execute. 1423 /// @param[in] arg Second argument to `luaeval()`. 1424 /// @param[out] ret_tv Location where result will be saved. 1425 /// 1426 /// @return Result of the execution. 1427 void nlua_typval_eval(const String str, typval_T *const arg, typval_T *const ret_tv) 1428 FUNC_ATTR_NONNULL_ALL 1429 { 1430 #define EVALHEADER "local _A=select(1,...) return (" 1431 const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1; 1432 char *lcmd; 1433 if (lcmd_len < IOSIZE) { 1434 lcmd = IObuff; 1435 } else { 1436 lcmd = xmalloc(lcmd_len); 1437 } 1438 memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1); 1439 memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size); 1440 lcmd[lcmd_len - 1] = ')'; 1441 #undef EVALHEADER 1442 nlua_typval_exec(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv); 1443 1444 if (lcmd != IObuff) { 1445 xfree(lcmd); 1446 } 1447 } 1448 1449 void nlua_typval_call(const char *str, size_t len, typval_T *const args, int argcount, 1450 typval_T *ret_tv) 1451 FUNC_ATTR_NONNULL_ALL 1452 { 1453 #define CALLHEADER "return " 1454 #define CALLSUFFIX "(...)" 1455 const size_t lcmd_len = sizeof(CALLHEADER) - 1 + len + sizeof(CALLSUFFIX) - 1; 1456 char *lcmd; 1457 if (lcmd_len < IOSIZE) { 1458 lcmd = IObuff; 1459 } else { 1460 lcmd = xmalloc(lcmd_len); 1461 } 1462 memcpy(lcmd, CALLHEADER, sizeof(CALLHEADER) - 1); 1463 memcpy(lcmd + sizeof(CALLHEADER) - 1, str, len); 1464 memcpy(lcmd + sizeof(CALLHEADER) - 1 + len, CALLSUFFIX, 1465 sizeof(CALLSUFFIX) - 1); 1466 #undef CALLHEADER 1467 #undef CALLSUFFIX 1468 1469 nlua_typval_exec(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv); 1470 1471 if (lcmd != IObuff) { 1472 xfree(lcmd); 1473 } 1474 } 1475 1476 void nlua_call_user_expand_func(expand_T *xp, typval_T *ret_tv) 1477 FUNC_ATTR_NONNULL_ALL 1478 { 1479 lua_State *const lstate = global_lstate; 1480 1481 nlua_pushref(lstate, xp->xp_luaref); 1482 lua_pushstring(lstate, xp->xp_pattern); 1483 lua_pushstring(lstate, xp->xp_line); 1484 lua_pushinteger(lstate, xp->xp_col); 1485 1486 if (nlua_pcall(lstate, 3, 1)) { 1487 nlua_error(lstate, _("E5108: Lua function: %.*s")); 1488 return; 1489 } 1490 1491 nlua_pop_typval(lstate, ret_tv); 1492 } 1493 1494 static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name, 1495 typval_T *const args, int argcount, bool special, typval_T *ret_tv) 1496 { 1497 if (check_secure()) { 1498 if (ret_tv) { 1499 ret_tv->v_type = VAR_NUMBER; 1500 ret_tv->vval.v_number = 0; 1501 } 1502 return; 1503 } 1504 1505 lua_State *const lstate = global_lstate; 1506 1507 if (luaL_loadbuffer(lstate, lcmd, lcmd_len, name)) { 1508 nlua_error(lstate, _("E5107: Lua: %.*s")); 1509 return; 1510 } 1511 1512 PUSH_ALL_TYPVALS(lstate, args, argcount, special); 1513 1514 if (nlua_pcall(lstate, argcount, ret_tv ? 1 : 0)) { 1515 nlua_error(lstate, _("E5108: Lua: %.*s")); 1516 return; 1517 } 1518 1519 if (ret_tv) { 1520 nlua_pop_typval(lstate, ret_tv); 1521 } 1522 } 1523 1524 void nlua_exec_ga(garray_T *ga, char *name) 1525 { 1526 char *code = ga_concat_strings(ga, "\n"); 1527 size_t len = strlen(code); 1528 nlua_typval_exec(code, len, name, NULL, 0, false, NULL); 1529 xfree(code); 1530 } 1531 1532 /// Call a LuaCallable given some typvals 1533 /// 1534 /// Used to call any Lua callable passed from Lua into Vimscript. 1535 /// 1536 /// @param[in] lstate Lua State 1537 /// @param[in] lua_cb Lua Callable 1538 /// @param[in] argcount Count of typval arguments 1539 /// @param[in] argvars Typval Arguments 1540 /// @param[out] rettv The return value from the called function. 1541 int typval_exec_lua_callable(LuaRef lua_cb, int argcount, typval_T *argvars, typval_T *rettv) 1542 { 1543 lua_State *lstate = global_lstate; 1544 1545 nlua_pushref(lstate, lua_cb); 1546 1547 PUSH_ALL_TYPVALS(lstate, argvars, argcount, false); 1548 1549 if (nlua_pcall(lstate, argcount, 1)) { 1550 nlua_error(lstate, _("Lua callback: %.*s")); 1551 return FCERR_OTHER; 1552 } 1553 1554 nlua_pop_typval(lstate, rettv); 1555 1556 return FCERR_NONE; 1557 } 1558 1559 /// Execute Lua string 1560 /// 1561 /// Used for nvim_exec_lua() and internally to execute a lua string. 1562 /// 1563 /// @param[in] str String to execute. 1564 /// @param[in] chunkname Chunkname, defaults to "<nvim>". 1565 /// @param[in] args array of ... args 1566 /// @param[in] mode Whether and how the the return value should be converted to Object 1567 /// @param[in] arena can be NULL, then nested allocations are used 1568 /// @param[out] err Location where error will be saved. 1569 /// 1570 /// @return Return value of the execution. 1571 Object nlua_exec(const String str, const char *chunkname, const Array args, LuaRetMode mode, 1572 Arena *arena, Error *err) 1573 { 1574 lua_State *const lstate = global_lstate; 1575 1576 int top = lua_gettop(lstate); 1577 const char *name = (chunkname && chunkname[0]) ? chunkname : "<nvim>"; 1578 if (luaL_loadbuffer(lstate, str.data, str.size, name)) { 1579 size_t len; 1580 const char *errstr = lua_tolstring(lstate, -1, &len); 1581 api_set_error(err, kErrorTypeValidation, "Lua: %.*s", (int)len, errstr); 1582 return NIL; 1583 } 1584 1585 for (size_t i = 0; i < args.size; i++) { 1586 nlua_push_Object(lstate, &args.items[i], 0); 1587 } 1588 1589 if (nlua_pcall(lstate, (int)args.size, 1)) { 1590 size_t len; 1591 const char *errstr = lua_tolstring(lstate, -1, &len); 1592 api_set_error(err, kErrorTypeException, "Lua: %.*s", (int)len, errstr); 1593 return NIL; 1594 } 1595 1596 return nlua_call_pop_retval(lstate, mode, arena, top, err); 1597 } 1598 1599 bool nlua_ref_is_function(LuaRef ref) 1600 { 1601 lua_State *const lstate = global_lstate; 1602 nlua_pushref(lstate, ref); 1603 1604 // TODO(tjdevries): This should probably check for callable tables as well. 1605 // We should put some work maybe into simplifying how all of that works 1606 bool is_function = (lua_type(lstate, -1) == LUA_TFUNCTION); 1607 lua_pop(lstate, 1); 1608 1609 return is_function; 1610 } 1611 1612 /// call a LuaRef as a function (or table with __call metamethod) 1613 /// 1614 /// @param ref the reference to call (not consumed) 1615 /// @param name if non-NULL, sent to callback as first arg 1616 /// if NULL, only args are used 1617 /// @param mode Whether and how the the return value should be converted to Object 1618 /// @param arena can be NULL, then nested allocations are used 1619 /// @param err Error details, if any (if NULL, errors are echoed) 1620 /// @return Return value of function, as per mode 1621 Object nlua_call_ref(LuaRef ref, const char *name, Array args, LuaRetMode mode, Arena *arena, 1622 Error *err) 1623 { 1624 return nlua_call_ref_ctx(false, ref, name, args, mode, arena, err); 1625 } 1626 1627 static int mode_ret(LuaRetMode mode) 1628 { 1629 return mode == kRetMulti ? LUA_MULTRET : 1; 1630 } 1631 1632 Object nlua_call_ref_ctx(bool fast, LuaRef ref, const char *name, Array args, LuaRetMode mode, 1633 Arena *arena, Error *err) 1634 { 1635 lua_State *const lstate = global_lstate; 1636 int top = lua_gettop(lstate); 1637 nlua_pushref(lstate, ref); 1638 int nargs = (int)args.size; 1639 if (name != NULL) { 1640 lua_pushstring(lstate, name); 1641 nargs++; 1642 } 1643 for (size_t i = 0; i < args.size; i++) { 1644 nlua_push_Object(lstate, &args.items[i], 0); 1645 } 1646 1647 if (fast) { 1648 if (nlua_fast_cfpcall(lstate, nargs, mode_ret(mode), -1) < 0) { 1649 // error is already scheduled, set anyways to convey failure. 1650 api_set_error(err, kErrorTypeException, "fast context failure"); 1651 return NIL; 1652 } 1653 } else if (nlua_pcall(lstate, nargs, mode_ret(mode))) { 1654 // if err is passed, the caller will deal with the error. 1655 if (err) { 1656 size_t len; 1657 const char *errstr = lua_tolstring(lstate, -1, &len); 1658 api_set_error(err, kErrorTypeException, "Lua: %.*s", (int)len, errstr); 1659 } else { 1660 nlua_error(lstate, _("Lua callback: %.*s")); 1661 } 1662 return NIL; 1663 } 1664 1665 return nlua_call_pop_retval(lstate, mode, arena, top, err); 1666 } 1667 1668 static Object nlua_call_pop_retval(lua_State *lstate, LuaRetMode mode, Arena *arena, int pretop, 1669 Error *err) 1670 { 1671 if (mode != kRetMulti && lua_isnil(lstate, -1)) { 1672 lua_pop(lstate, 1); 1673 return NIL; 1674 } 1675 Error dummy = ERROR_INIT; 1676 Error *perr = err ? err : &dummy; 1677 1678 switch (mode) { 1679 case kRetNilBool: { 1680 bool bool_value = lua_toboolean(lstate, -1); 1681 lua_pop(lstate, 1); 1682 1683 return BOOLEAN_OBJ(bool_value); 1684 } 1685 case kRetLuaref: { 1686 LuaRef ref = nlua_ref_global(lstate, -1); 1687 lua_pop(lstate, 1); 1688 1689 return LUAREF_OBJ(ref); 1690 } 1691 case kRetObject: 1692 return nlua_pop_Object(lstate, false, arena, perr); 1693 case kRetMulti: 1694 ; 1695 int nres = lua_gettop(lstate) - pretop; 1696 Array res = arena_array(arena, (size_t)nres); 1697 for (int i = 0; i < nres; i++) { 1698 res.items[nres - i - 1] = nlua_pop_Object(lstate, false, arena, perr); 1699 if (ERROR_SET(perr)) { 1700 return NIL; 1701 } 1702 } 1703 res.size = (size_t)nres; 1704 return ARRAY_OBJ(res); 1705 } 1706 UNREACHABLE; 1707 } 1708 1709 /// check if the current execution context is safe for calling deferred API 1710 /// methods. Luv callbacks are unsafe as they are called inside the uv loop. 1711 bool nlua_is_deferred_safe(void) 1712 { 1713 return in_fast_callback == 0; 1714 } 1715 1716 /// Executes Lua code. 1717 /// 1718 /// Implements `:lua` and `:lua ={expr}`. 1719 /// 1720 /// @param eap Vimscript `:lua {code}`, `:{range}lua`, or `:lua ={expr}` command. 1721 void ex_lua(exarg_T *const eap) 1722 FUNC_ATTR_NONNULL_ALL 1723 { 1724 // ":{range}lua", only if no {code} 1725 if (*eap->arg == NUL) { 1726 if (eap->addr_count > 0) { 1727 cmd_source_buffer(eap, true); 1728 } else { 1729 emsg(_(e_argreq)); 1730 } 1731 return; 1732 } 1733 1734 size_t len; 1735 char *code = script_get(eap, &len); 1736 if (eap->skip || code == NULL) { 1737 xfree(code); 1738 return; 1739 } 1740 1741 // ":lua {code}", ":={expr}" or ":lua ={expr}" 1742 // 1743 // When "=expr" is used transform it to "vim._print(true, expr)". 1744 if (eap->cmdidx == CMD_equal || code[0] == '=') { 1745 size_t off = (eap->cmdidx == CMD_equal) ? 0 : 1; 1746 len += sizeof("vim._print(true, )") - 1 - off; 1747 // `nlua_typval_exec` doesn't expect NUL-terminated string so `len` must end before NUL byte. 1748 char *code_buf = xmallocz(len); 1749 vim_snprintf(code_buf, len + 1, "vim._print(true, %s)", code + off); 1750 xfree(code); 1751 code = code_buf; 1752 } 1753 1754 nlua_typval_exec(code, len, ":lua", NULL, 0, false, NULL); 1755 1756 xfree(code); 1757 } 1758 1759 /// Executes Lua code for-each line in a buffer range. 1760 /// 1761 /// Implements `:luado`. 1762 /// 1763 /// @param eap Vimscript `:luado {code}` command. 1764 void ex_luado(exarg_T *const eap) 1765 FUNC_ATTR_NONNULL_ALL 1766 { 1767 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) { 1768 emsg(_("cannot save undo information")); 1769 return; 1770 } 1771 const char *const cmd = eap->arg; 1772 const size_t cmd_len = strlen(cmd); 1773 1774 lua_State *const lstate = global_lstate; 1775 1776 #define DOSTART "return function(line, linenr) " 1777 #define DOEND " end" 1778 const size_t lcmd_len = (cmd_len 1779 + (sizeof(DOSTART) - 1) 1780 + (sizeof(DOEND) - 1)); 1781 char *lcmd; 1782 if (lcmd_len < IOSIZE) { 1783 lcmd = IObuff; 1784 } else { 1785 lcmd = xmalloc(lcmd_len + 1); 1786 } 1787 memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1); 1788 memcpy(lcmd + sizeof(DOSTART) - 1, cmd, cmd_len); 1789 memcpy(lcmd + sizeof(DOSTART) - 1 + cmd_len, DOEND, sizeof(DOEND) - 1); 1790 #undef DOSTART 1791 #undef DOEND 1792 1793 if (luaL_loadbuffer(lstate, lcmd, lcmd_len, ":luado")) { 1794 nlua_error(lstate, _("E5109: Lua: %.*s")); 1795 if (lcmd_len >= IOSIZE) { 1796 xfree(lcmd); 1797 } 1798 return; 1799 } 1800 if (lcmd_len >= IOSIZE) { 1801 xfree(lcmd); 1802 } 1803 if (nlua_pcall(lstate, 0, 1)) { 1804 nlua_error(lstate, _("E5110: Lua: %.*s")); 1805 return; 1806 } 1807 1808 buf_T *const was_curbuf = curbuf; 1809 1810 for (linenr_T l = eap->line1; l <= eap->line2; l++) { 1811 // Check the line number, the command may have deleted lines. 1812 if (l > curbuf->b_ml.ml_line_count) { 1813 break; 1814 } 1815 1816 lua_pushvalue(lstate, -1); 1817 const char *const old_line = ml_get_buf(curbuf, l); 1818 // Get length of old_line here as calling Lua code may free it. 1819 const colnr_T old_line_len = ml_get_buf_len(curbuf, l); 1820 lua_pushstring(lstate, old_line); 1821 lua_pushnumber(lstate, (lua_Number)l); 1822 if (nlua_pcall(lstate, 2, 1)) { 1823 nlua_error(lstate, _("E5111: Lua: %.*s")); 1824 break; 1825 } 1826 1827 // Catch the command switching to another buffer. 1828 // Check the line number, the command may have deleted lines. 1829 if (curbuf != was_curbuf || l > curbuf->b_ml.ml_line_count) { 1830 break; 1831 } 1832 1833 if (lua_isstring(lstate, -1)) { 1834 size_t new_line_len; 1835 const char *const new_line = lua_tolstring(lstate, -1, &new_line_len); 1836 char *const new_line_transformed = xmemdupz(new_line, new_line_len); 1837 for (size_t i = 0; i < new_line_len; i++) { 1838 if (new_line_transformed[i] == NUL) { 1839 new_line_transformed[i] = '\n'; 1840 } 1841 } 1842 ml_replace(l, new_line_transformed, false); 1843 inserted_bytes(l, 0, old_line_len, (int)new_line_len); 1844 } 1845 lua_pop(lstate, 1); 1846 } 1847 1848 lua_pop(lstate, 1); 1849 check_cursor(curwin); 1850 redraw_curbuf_later(UPD_NOT_VALID); 1851 } 1852 1853 /// Executes Lua code from a file location. 1854 /// 1855 /// Implements `:luafile`. 1856 /// 1857 /// @param eap Vimscript `:luafile {file}` command. 1858 void ex_luafile(exarg_T *const eap) 1859 FUNC_ATTR_NONNULL_ALL 1860 { 1861 nlua_exec_file(eap->arg); 1862 } 1863 1864 /// Executes Lua code from a file or "-" (stdin). 1865 /// 1866 /// Calls the Lua `loadfile` global as opposed to `luaL_loadfile` in case `loadfile` was overridden 1867 /// in the user environment. 1868 /// 1869 /// @param path Path to the file, may be "-" (stdin) during startup. 1870 /// 1871 /// @return true on success, false on error (echoed) or user canceled (CTRL-c) while reading "-" 1872 /// (stdin). 1873 bool nlua_exec_file(const char *path) 1874 FUNC_ATTR_NONNULL_ALL 1875 { 1876 lua_State *const lstate = global_lstate; 1877 if (!strequal(path, "-")) { 1878 lua_getglobal(lstate, "loadfile"); 1879 lua_pushstring(lstate, path); 1880 } else { 1881 FileDescriptor stdin_dup; 1882 int error = file_open_stdin(&stdin_dup); 1883 if (error) { 1884 return false; 1885 } 1886 1887 StringBuilder sb = KV_INITIAL_VALUE; 1888 kv_resize(sb, 64); 1889 // Read all input from stdin, unless interrupted (ctrl-c). 1890 while (true) { 1891 if (got_int) { // User canceled. 1892 file_close(&stdin_dup, false); 1893 kv_destroy(sb); 1894 return false; 1895 } 1896 ptrdiff_t read_size = file_read(&stdin_dup, IObuff, 64); 1897 if (read_size < 0) { // Error. 1898 file_close(&stdin_dup, false); 1899 kv_destroy(sb); 1900 return false; 1901 } 1902 if (read_size > 0) { 1903 kv_concat_len(sb, IObuff, (size_t)read_size); 1904 } 1905 if (read_size < 64) { // EOF. 1906 break; 1907 } 1908 } 1909 kv_push(sb, NUL); 1910 file_close(&stdin_dup, false); 1911 1912 lua_getglobal(lstate, "loadstring"); 1913 lua_pushstring(lstate, sb.items); 1914 kv_destroy(sb); 1915 } 1916 1917 if (nlua_pcall(lstate, 1, 2)) { 1918 nlua_error(lstate, _("E5111: Lua: %.*s")); 1919 return false; 1920 } 1921 1922 // loadstring() returns either: 1923 // 1. nil, error 1924 // 2. chunk, nil 1925 1926 if (lua_isnil(lstate, -2)) { 1927 // 1 1928 nlua_error(lstate, _("E5112: Lua chunk: %.*s")); 1929 assert(lua_isnil(lstate, -1)); 1930 lua_pop(lstate, 1); 1931 return false; 1932 } 1933 1934 // 2 1935 assert(lua_isnil(lstate, -1)); 1936 lua_pop(lstate, 1); 1937 1938 if (nlua_pcall(lstate, 0, 0)) { 1939 nlua_error(lstate, _("E5113: Lua chunk: %.*s")); 1940 return false; 1941 } 1942 1943 return true; 1944 } 1945 1946 static garray_T expand_result_array = GA_EMPTY_INIT_VALUE; 1947 1948 /// Finds matches for Lua cmdline completion and advances xp->xp_pattern after prefix. 1949 /// This should be called before xp->xp_pattern is first used. 1950 void nlua_expand_pat(expand_T *xp) 1951 { 1952 lua_State *const lstate = global_lstate; 1953 int status = FAIL; 1954 1955 // [ vim ] 1956 lua_getglobal(lstate, "vim"); 1957 1958 // [ vim, vim._expand_pat ] 1959 lua_getfield(lstate, -1, "_expand_pat"); 1960 luaL_checktype(lstate, -1, LUA_TFUNCTION); 1961 1962 // [ vim, vim._expand_pat, pat ] 1963 const char *pat = xp->xp_pattern; 1964 assert(xp->xp_line + xp->xp_col >= pat); 1965 ptrdiff_t patlen = xp->xp_line + xp->xp_col - pat; 1966 lua_pushlstring(lstate, pat, (size_t)patlen); 1967 1968 if (nlua_pcall(lstate, 1, 2) != 0) { 1969 nlua_error(lstate, _("vim._expand_pat: %.*s")); 1970 return; 1971 } 1972 1973 Error err = ERROR_INIT; 1974 1975 Arena arena = ARENA_EMPTY; 1976 ptrdiff_t prefix_len = nlua_pop_Integer(lstate, &arena, &err); 1977 if (ERROR_SET(&err) || prefix_len > patlen) { 1978 goto cleanup; 1979 } 1980 1981 Array completions = nlua_pop_Array(lstate, &arena, &err); 1982 if (ERROR_SET(&err)) { 1983 goto cleanup_array; 1984 } 1985 1986 ga_clear(&expand_result_array); 1987 ga_init(&expand_result_array, (int)sizeof(char *), 80); 1988 1989 for (size_t i = 0; i < completions.size; i++) { 1990 Object v = completions.items[i]; 1991 if (v.type != kObjectTypeString) { 1992 goto cleanup_array; 1993 } 1994 GA_APPEND(char *, &expand_result_array, string_to_cstr(v.data.string)); 1995 } 1996 1997 xp->xp_pattern += prefix_len; 1998 status = OK; 1999 2000 cleanup_array: 2001 arena_mem_free(arena_finish(&arena)); 2002 2003 cleanup: 2004 if (status == FAIL) { 2005 ga_clear(&expand_result_array); 2006 } 2007 } 2008 2009 int nlua_expand_get_matches(int *num_results, char ***results) 2010 { 2011 *results = expand_result_array.ga_data; 2012 *num_results = expand_result_array.ga_len; 2013 expand_result_array = (garray_T)GA_EMPTY_INIT_VALUE; 2014 return *num_results > 0; 2015 } 2016 2017 static int nlua_is_thread(lua_State *lstate) 2018 { 2019 lua_getfield(lstate, LUA_REGISTRYINDEX, "nvim.thread"); 2020 2021 return 1; 2022 } 2023 2024 bool nlua_is_table_from_lua(const typval_T *const arg) 2025 { 2026 if (arg->v_type == VAR_DICT) { 2027 return arg->vval.v_dict->lua_table_ref != LUA_NOREF; 2028 } else if (arg->v_type == VAR_LIST) { 2029 return arg->vval.v_list->lua_table_ref != LUA_NOREF; 2030 } else { 2031 return false; 2032 } 2033 } 2034 2035 char *nlua_register_table_as_callable(const typval_T *const arg) 2036 { 2037 LuaRef table_ref = LUA_NOREF; 2038 if (arg->v_type == VAR_DICT) { 2039 table_ref = arg->vval.v_dict->lua_table_ref; 2040 } else if (arg->v_type == VAR_LIST) { 2041 table_ref = arg->vval.v_list->lua_table_ref; 2042 } 2043 2044 if (table_ref == LUA_NOREF) { 2045 return NULL; 2046 } 2047 2048 lua_State *const lstate = global_lstate; 2049 2050 #ifndef NDEBUG 2051 int top = lua_gettop(lstate); 2052 #endif 2053 2054 nlua_pushref(lstate, table_ref); // [table] 2055 if (!lua_getmetatable(lstate, -1)) { 2056 lua_pop(lstate, 1); 2057 assert(top == lua_gettop(lstate)); 2058 return NULL; 2059 } // [table, mt] 2060 2061 lua_getfield(lstate, -1, "__call"); // [table, mt, mt.__call] 2062 if (!lua_isfunction(lstate, -1)) { 2063 lua_pop(lstate, 3); 2064 assert(top == lua_gettop(lstate)); 2065 return NULL; 2066 } 2067 lua_pop(lstate, 2); // [table] 2068 2069 LuaRef func = nlua_ref_global(lstate, -1); 2070 2071 char *name = register_luafunc(func); 2072 2073 lua_pop(lstate, 1); // [] 2074 assert(top == lua_gettop(lstate)); 2075 2076 return name; 2077 } 2078 2079 /// @return true to discard the key 2080 bool nlua_execute_on_key(int c, char *typed_buf) 2081 { 2082 static bool recursive = false; 2083 2084 if (recursive) { 2085 return false; 2086 } 2087 recursive = true; 2088 2089 char buf[MB_MAXBYTES * 3 + 4]; 2090 size_t buf_len = special_to_buf(c, mod_mask, false, buf); 2091 vim_unescape_ks(typed_buf); 2092 2093 lua_State *const lstate = global_lstate; 2094 2095 #ifndef NDEBUG 2096 int top = lua_gettop(lstate); 2097 #endif 2098 2099 // [ vim ] 2100 lua_getglobal(lstate, "vim"); 2101 2102 // [ vim, vim._on_key ] 2103 lua_getfield(lstate, -1, "_on_key"); 2104 luaL_checktype(lstate, -1, LUA_TFUNCTION); 2105 2106 // [ vim, vim._on_key, buf ] 2107 lua_pushlstring(lstate, buf, buf_len); 2108 2109 // [ vim, vim._on_key, buf, typed_buf ] 2110 lua_pushstring(lstate, typed_buf); 2111 2112 int save_got_int = got_int; 2113 got_int = false; // avoid interrupts when the key typed is Ctrl-C 2114 bool discard = false; 2115 // Do not use nlua_pcall here to avoid duplicate stack trace information 2116 if (lua_pcall(lstate, 2, 1, 0)) { 2117 nlua_error(lstate, _("vim.on_key() callbacks: %.*s")); 2118 } else { 2119 if (lua_isboolean(lstate, -1)) { 2120 discard = lua_toboolean(lstate, -1); 2121 } 2122 lua_pop(lstate, 1); 2123 } 2124 got_int |= save_got_int; 2125 2126 // [ vim ] 2127 lua_pop(lstate, 1); 2128 2129 #ifndef NDEBUG 2130 // [ ] 2131 assert(top == lua_gettop(lstate)); 2132 #endif 2133 2134 recursive = false; 2135 return discard; 2136 } 2137 2138 /// Sets the editor "script context" during Lua execution. Used by :verbose. 2139 /// @param[out] current 2140 void nlua_set_sctx(sctx_T *current) 2141 { 2142 if (!script_is_lua(current->sc_sid)) { 2143 return; 2144 } 2145 2146 // This function is called after adding SOURCING_LNUM to sc_lnum. 2147 // SOURCING_LNUM can sometimes be non-zero (e.g. with ETYPE_UFUNC), 2148 // but it's unrelated to the line number in Lua scripts. 2149 current->sc_lnum = 0; 2150 2151 if (p_verbose <= 0) { 2152 return; 2153 } 2154 lua_State *const lstate = active_lstate; 2155 lua_Debug *info = (lua_Debug *)xmalloc(sizeof(lua_Debug)); 2156 2157 // Files where internal wrappers are defined so we can ignore them 2158 // like vim.o/opt etc are defined in _options.lua 2159 char *ignorelist[] = { 2160 "vim/_core/editor.lua", 2161 "vim/_core/options.lua", 2162 "vim/keymap.lua", 2163 }; 2164 int ignorelist_size = sizeof(ignorelist) / sizeof(ignorelist[0]); 2165 2166 for (int level = 1; true; level++) { 2167 if (lua_getstack(lstate, level, info) != 1) { 2168 goto cleanup; 2169 } 2170 if (lua_getinfo(lstate, "nSl", info) == 0) { 2171 goto cleanup; 2172 } 2173 2174 bool is_ignored = false; 2175 if (info->what[0] == 'C' || info->source[0] != '@') { 2176 is_ignored = true; 2177 } else { 2178 for (int i = 0; i < ignorelist_size; i++) { 2179 if (strncmp(ignorelist[i], info->source + 1, strlen(ignorelist[i])) == 0) { 2180 is_ignored = true; 2181 break; 2182 } 2183 } 2184 } 2185 if (is_ignored) { 2186 continue; 2187 } 2188 break; 2189 } 2190 char *source_path = fix_fname(info->source + 1); 2191 int sid = find_script_by_name(source_path); 2192 if (sid > 0) { 2193 xfree(source_path); 2194 } else { 2195 scriptitem_T *si = new_script_item(source_path, &sid); 2196 si->sn_lua = true; 2197 } 2198 current->sc_sid = sid; 2199 current->sc_seq = -1; 2200 current->sc_lnum = info->currentline; 2201 2202 cleanup: 2203 xfree(info); 2204 } 2205 2206 /// @param preview Invoke the callback as a |:command-preview| handler. 2207 int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview) 2208 { 2209 lua_State *const lstate = global_lstate; 2210 2211 nlua_pushref(lstate, preview ? cmd->uc_preview_luaref : cmd->uc_luaref); 2212 2213 lua_newtable(lstate); 2214 lua_pushstring(lstate, cmd->uc_name); 2215 lua_setfield(lstate, -2, "name"); 2216 2217 lua_pushboolean(lstate, eap->forceit == 1); 2218 lua_setfield(lstate, -2, "bang"); 2219 2220 lua_pushinteger(lstate, eap->line1); 2221 lua_setfield(lstate, -2, "line1"); 2222 2223 lua_pushinteger(lstate, eap->line2); 2224 lua_setfield(lstate, -2, "line2"); 2225 2226 lua_newtable(lstate); // f-args table 2227 lua_pushstring(lstate, eap->arg); 2228 lua_pushvalue(lstate, -1); // Reference for potential use on f-args 2229 lua_setfield(lstate, -4, "args"); 2230 2231 // Split args by unescaped whitespace |<f-args>| (nargs dependent) 2232 if (cmd->uc_argt & EX_NOSPC) { 2233 if ((cmd->uc_argt & EX_NEEDARG) || strlen(eap->arg)) { 2234 // For commands where nargs is 1 or "?" and argument is passed, fargs = { args } 2235 lua_rawseti(lstate, -2, 1); 2236 } else { 2237 // if nargs = "?" and no argument is passed, fargs = {} 2238 lua_pop(lstate, 1); // Pop the reference of opts.args 2239 } 2240 } else if (eap->args == NULL) { 2241 // For commands with more than one possible argument, split if argument list isn't available. 2242 lua_pop(lstate, 1); // Pop the reference of opts.args 2243 size_t length = strlen(eap->arg); 2244 size_t end = 0; 2245 size_t len = 0; 2246 int i = 1; 2247 char *buf = xcalloc(length, sizeof(char)); 2248 bool done = false; 2249 while (!done) { 2250 done = uc_split_args_iter(eap->arg, length, &end, buf, &len); 2251 if (len > 0) { 2252 lua_pushlstring(lstate, buf, len); 2253 lua_rawseti(lstate, -2, i); 2254 i++; 2255 } 2256 } 2257 xfree(buf); 2258 } else { 2259 // If argument list is available, just use it. 2260 lua_pop(lstate, 1); 2261 for (size_t i = 0; i < eap->argc; i++) { 2262 lua_pushlstring(lstate, eap->args[i], eap->arglens[i]); 2263 lua_rawseti(lstate, -2, (int)i + 1); 2264 } 2265 } 2266 lua_setfield(lstate, -2, "fargs"); 2267 2268 char reg[2] = { (char)eap->regname, NUL }; 2269 lua_pushstring(lstate, reg); 2270 lua_setfield(lstate, -2, "reg"); 2271 2272 lua_pushinteger(lstate, eap->addr_count); 2273 lua_setfield(lstate, -2, "range"); 2274 2275 if (eap->addr_count > 0) { 2276 lua_pushinteger(lstate, eap->line2); 2277 } else { 2278 lua_pushinteger(lstate, cmd->uc_def); 2279 } 2280 lua_setfield(lstate, -2, "count"); 2281 2282 char nargs[2]; 2283 if (cmd->uc_argt & EX_EXTRA) { 2284 if (cmd->uc_argt & EX_NOSPC) { 2285 if (cmd->uc_argt & EX_NEEDARG) { 2286 nargs[0] = '1'; 2287 } else { 2288 nargs[0] = '?'; 2289 } 2290 } else if (cmd->uc_argt & EX_NEEDARG) { 2291 nargs[0] = '+'; 2292 } else { 2293 nargs[0] = '*'; 2294 } 2295 } else { 2296 nargs[0] = '0'; 2297 } 2298 nargs[1] = NUL; 2299 lua_pushstring(lstate, nargs); 2300 lua_setfield(lstate, -2, "nargs"); 2301 2302 // The size of this buffer is chosen empirically to be large enough to hold 2303 // every possible modifier (with room to spare). If the list of possible 2304 // modifiers grows this may need to be updated. 2305 char buf[200] = { 0 }; 2306 uc_mods(buf, &cmdmod, false); 2307 lua_pushstring(lstate, buf); 2308 lua_setfield(lstate, -2, "mods"); 2309 2310 lua_newtable(lstate); // smods table 2311 2312 lua_pushinteger(lstate, cmdmod.cmod_tab - 1); 2313 lua_setfield(lstate, -2, "tab"); 2314 2315 lua_pushinteger(lstate, cmdmod.cmod_verbose - 1); 2316 lua_setfield(lstate, -2, "verbose"); 2317 2318 if (cmdmod.cmod_split & WSP_ABOVE) { 2319 lua_pushstring(lstate, "aboveleft"); 2320 } else if (cmdmod.cmod_split & WSP_BELOW) { 2321 lua_pushstring(lstate, "belowright"); 2322 } else if (cmdmod.cmod_split & WSP_TOP) { 2323 lua_pushstring(lstate, "topleft"); 2324 } else if (cmdmod.cmod_split & WSP_BOT) { 2325 lua_pushstring(lstate, "botright"); 2326 } else { 2327 lua_pushstring(lstate, ""); 2328 } 2329 lua_setfield(lstate, -2, "split"); 2330 2331 lua_pushboolean(lstate, cmdmod.cmod_split & WSP_VERT); 2332 lua_setfield(lstate, -2, "vertical"); 2333 lua_pushboolean(lstate, cmdmod.cmod_split & WSP_HOR); 2334 lua_setfield(lstate, -2, "horizontal"); 2335 lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_SILENT); 2336 lua_setfield(lstate, -2, "silent"); 2337 lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_ERRSILENT); 2338 lua_setfield(lstate, -2, "emsg_silent"); 2339 lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_UNSILENT); 2340 lua_setfield(lstate, -2, "unsilent"); 2341 lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_SANDBOX); 2342 lua_setfield(lstate, -2, "sandbox"); 2343 lua_pushboolean(lstate, cmdmod.cmod_flags & CMOD_NOAUTOCMD); 2344 lua_setfield(lstate, -2, "noautocmd"); 2345 2346 typedef struct { 2347 int flag; 2348 char *name; 2349 } mod_entry_T; 2350 static mod_entry_T mod_entries[] = { 2351 { CMOD_BROWSE, "browse" }, 2352 { CMOD_CONFIRM, "confirm" }, 2353 { CMOD_HIDE, "hide" }, 2354 { CMOD_KEEPALT, "keepalt" }, 2355 { CMOD_KEEPJUMPS, "keepjumps" }, 2356 { CMOD_KEEPMARKS, "keepmarks" }, 2357 { CMOD_KEEPPATTERNS, "keeppatterns" }, 2358 { CMOD_LOCKMARKS, "lockmarks" }, 2359 { CMOD_NOSWAPFILE, "noswapfile" } 2360 }; 2361 2362 // The modifiers that are simple flags 2363 for (size_t i = 0; i < ARRAY_SIZE(mod_entries); i++) { 2364 lua_pushboolean(lstate, cmdmod.cmod_flags & mod_entries[i].flag); 2365 lua_setfield(lstate, -2, mod_entries[i].name); 2366 } 2367 2368 lua_setfield(lstate, -2, "smods"); 2369 2370 if (preview) { 2371 lua_pushinteger(lstate, cmdpreview_get_ns()); 2372 2373 handle_T cmdpreview_bufnr = cmdpreview_get_bufnr(); 2374 if (cmdpreview_bufnr != 0) { 2375 lua_pushinteger(lstate, cmdpreview_bufnr); 2376 } else { 2377 lua_pushnil(lstate); 2378 } 2379 } 2380 2381 if (nlua_pcall(lstate, preview ? 3 : 1, preview ? 1 : 0)) { 2382 nlua_error(lstate, _("Lua :command callback: %.*s")); 2383 return 0; 2384 } 2385 2386 int retv = 0; 2387 2388 if (preview) { 2389 if (lua_isnumber(lstate, -1) && (retv = (int)lua_tointeger(lstate, -1)) >= 0 && retv <= 2) { 2390 lua_pop(lstate, 1); 2391 } else { 2392 retv = 0; 2393 } 2394 } 2395 2396 return retv; 2397 } 2398 2399 /// String representation of a Lua function reference 2400 /// 2401 /// @return Allocated string 2402 char *nlua_funcref_str(LuaRef ref, Arena *arena) 2403 { 2404 lua_State *const lstate = global_lstate; 2405 2406 if (!lua_checkstack(lstate, 1)) { 2407 goto plain; 2408 } 2409 nlua_pushref(lstate, ref); 2410 if (!lua_isfunction(lstate, -1)) { 2411 lua_pop(lstate, 1); 2412 goto plain; 2413 } 2414 2415 lua_Debug ar; 2416 if (lua_getinfo(lstate, ">S", &ar) && *ar.source == '@' && ar.linedefined >= 0) { 2417 char *src = home_replace_save(NULL, ar.source + 1); 2418 String str = arena_printf(arena, "<Lua %d: %s:%d>", ref, src, ar.linedefined); 2419 xfree(src); 2420 return str.data; 2421 } 2422 2423 plain: {} 2424 return arena_printf(arena, "<Lua %d>", ref).data; 2425 } 2426 2427 /// Execute the vim._core.defaults module to set up default mappings and autocommands 2428 void nlua_init_defaults(void) 2429 { 2430 lua_State *const L = global_lstate; 2431 assert(L); 2432 2433 lua_getglobal(L, "require"); 2434 lua_pushstring(L, "vim._core.defaults"); 2435 if (nlua_pcall(L, 1, 0)) { 2436 fprintf(stderr, "%s\n", lua_tostring(L, -1)); 2437 } 2438 } 2439 2440 /// check lua function exist 2441 bool nlua_func_exists(const char *lua_funcname) 2442 { 2443 MAXSIZE_TEMP_ARRAY(args, 1); 2444 size_t length = strlen(lua_funcname) + 8; 2445 char *str = xmalloc(length); 2446 vim_snprintf(str, length, "return %s", lua_funcname); 2447 ADD_C(args, CSTR_AS_OBJ(str)); 2448 Error err = ERROR_INIT; 2449 Object result = NLUA_EXEC_STATIC("return type(loadstring(...)()) == 'function'", args, 2450 kRetNilBool, NULL, &err); 2451 xfree(str); 2452 2453 api_clear_error(&err); 2454 return LUARET_TRUTHY(result); 2455 }