1 // This is an open source non-commercial project. Dear PVS-Studio, please check
2 // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3 
4 #include <lauxlib.h>
5 #include <lua.h>
6 #include <lualib.h>
7 
8 #include "luv/luv.h"
9 #include "nvim/api/private/defs.h"
10 #include "nvim/api/private/helpers.h"
11 #include "nvim/api/vim.h"
12 #include "nvim/ascii.h"
13 #include "nvim/assert.h"
14 #include "nvim/buffer_defs.h"
15 #include "nvim/change.h"
16 #include "nvim/cursor.h"
17 #include "nvim/eval/userfunc.h"
18 #include "nvim/event/loop.h"
19 #include "nvim/event/time.h"
20 #include "nvim/ex_cmds2.h"
21 #include "nvim/ex_getln.h"
22 #include "nvim/extmark.h"
23 #include "nvim/func_attr.h"
24 #include "nvim/garray.h"
25 #include "nvim/getchar.h"
26 #include "nvim/lua/converter.h"
27 #include "nvim/lua/executor.h"
28 #include "nvim/lua/stdlib.h"
29 #include "nvim/lua/treesitter.h"
30 #include "nvim/macros.h"
31 #include "nvim/map.h"
32 #include "nvim/memline.h"
33 #include "nvim/message.h"
34 #include "nvim/misc1.h"
35 #include "nvim/msgpack_rpc/channel.h"
36 #include "nvim/os/os.h"
37 #include "nvim/screen.h"
38 #include "nvim/undo.h"
39 #include "nvim/version.h"
40 #include "nvim/vim.h"
41 
42 static int in_fast_callback = 0;
43 
44 // Initialized in nlua_init().
45 static lua_State *global_lstate = NULL;
46 
47 typedef struct {
48   Error err;
49   String lua_err_str;
50 } LuaError;
51 
52 #ifdef INCLUDE_GENERATED_DECLARATIONS
53 # include "lua/executor.c.generated.h"
54 # include "lua/vim_module.generated.h"
55 #endif
56 
57 #define PUSH_ALL_TYPVALS(lstate, args, argcount, special) \
58   for (int i = 0; i < argcount; i++) { \
59     if (args[i].v_type == VAR_UNKNOWN) { \
60       lua_pushnil(lstate); \
61     } else { \
62       nlua_push_typval(lstate, &args[i], special); \
63     } \
64   }
65 
66 #if __has_feature(address_sanitizer)
67 static PMap(handle_T) nlua_ref_markers = MAP_INIT;
68 static bool nlua_track_refs = false;
69 # define NLUA_TRACK_REFS
70 #endif
71 
72 /// Convert lua error into a Vim error message
73 ///
74 /// @param  lstate  Lua interpreter state.
75 /// @param[in]  msg  Message base, must contain one `%s`.
nlua_error(lua_State * const lstate,const char * const msg)76 static void nlua_error(lua_State *const lstate, const char *const msg)
77   FUNC_ATTR_NONNULL_ALL
78 {
79   size_t len;
80   const char *const str = lua_tolstring(lstate, -1, &len);
81 
82   msg_ext_set_kind("lua_error");
83   semsg_multiline(msg, (int)len, str);
84 
85   lua_pop(lstate, 1);
86 }
87 
88 /// Like lua_pcall, but use debug.traceback as errfunc.
89 ///
90 /// @param lstate Lua interpreter state
91 /// @param[in] nargs Number of arguments expected by the function being called.
92 /// @param[in] nresults Number of results the function returns.
nlua_pcall(lua_State * lstate,int nargs,int nresults)93 static int nlua_pcall(lua_State *lstate, int nargs, int nresults)
94 {
95   lua_getglobal(lstate, "debug");
96   lua_getfield(lstate, -1, "traceback");
97   lua_remove(lstate, -2);
98   lua_insert(lstate, -2 - nargs);
99   int status = lua_pcall(lstate, nargs, nresults, -2 - nargs);
100   if (status) {
101     lua_remove(lstate, -2);
102   } else {
103     lua_remove(lstate, -1 - nresults);
104   }
105   return status;
106 }
107 
108 
109 /// Gets the version of the current Nvim build.
110 ///
111 /// @param  lstate  Lua interpreter state.
nlua_nvim_version(lua_State * const lstate)112 static int nlua_nvim_version(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
113 {
114   Dictionary version = version_dict();
115   nlua_push_Dictionary(lstate, version, true);
116   api_free_dictionary(version);
117   return 1;
118 }
119 
120 
nlua_luv_error_event(void ** argv)121 static void nlua_luv_error_event(void **argv)
122 {
123   char *error = (char *)argv[0];
124   msg_ext_set_kind("lua_error");
125   semsg_multiline("Error executing luv callback:\n%s", error);
126   xfree(error);
127 }
128 
nlua_luv_cfpcall(lua_State * lstate,int nargs,int nresult,int flags)129 static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags)
130   FUNC_ATTR_NONNULL_ALL
131 {
132   int retval;
133 
134   // luv callbacks might be executed at any os_breakcheck/line_breakcheck
135   // call, so using the API directly here is not safe.
136   in_fast_callback++;
137 
138   int top = lua_gettop(lstate);
139   int status = nlua_pcall(lstate, nargs, nresult);
140   if (status) {
141     if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) {
142       // consider out of memory errors unrecoverable, just like xmalloc()
143       mch_errmsg(e_outofmem);
144       mch_errmsg("\n");
145       preserve_exit();
146     }
147     const char *error = lua_tostring(lstate, -1);
148 
149     multiqueue_put(main_loop.events, nlua_luv_error_event,
150                    1, xstrdup(error));
151     lua_pop(lstate, 1);  // error message
152     retval = -status;
153   } else {  // LUA_OK
154     if (nresult == LUA_MULTRET) {
155       nresult = lua_gettop(lstate) - top + nargs + 1;
156     }
157     retval = nresult;
158   }
159 
160   in_fast_callback--;
161   return retval;
162 }
163 
nlua_schedule_event(void ** argv)164 static void nlua_schedule_event(void **argv)
165 {
166   LuaRef cb = (LuaRef)(ptrdiff_t)argv[0];
167   lua_State *const lstate = global_lstate;
168   nlua_pushref(lstate, cb);
169   nlua_unref(lstate, cb);
170   if (nlua_pcall(lstate, 0, 0)) {
171     nlua_error(lstate, _("Error executing vim.schedule lua callback: %.*s"));
172   }
173 }
174 
175 /// Schedule Lua callback on main loop's event queue
176 ///
177 /// @param  lstate  Lua interpreter state.
nlua_schedule(lua_State * const lstate)178 static int nlua_schedule(lua_State *const lstate)
179   FUNC_ATTR_NONNULL_ALL
180 {
181   if (lua_type(lstate, 1) != LUA_TFUNCTION) {
182     lua_pushliteral(lstate, "vim.schedule: expected function");
183     return lua_error(lstate);
184   }
185 
186   LuaRef cb = nlua_ref(lstate, 1);
187 
188   multiqueue_put(main_loop.events, nlua_schedule_event,
189                  1, (void *)(ptrdiff_t)cb);
190   return 0;
191 }
192 
193 // Dummy timer callback. Used by f_wait().
dummy_timer_due_cb(TimeWatcher * tw,void * data)194 static void dummy_timer_due_cb(TimeWatcher *tw, void *data)
195 {
196 }
197 
198 // Dummy timer close callback. Used by f_wait().
dummy_timer_close_cb(TimeWatcher * tw,void * data)199 static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
200 {
201   xfree(tw);
202 }
203 
nlua_wait_condition(lua_State * lstate,int * status,bool * callback_result)204 static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_result)
205 {
206   lua_pushvalue(lstate, 2);
207   *status = nlua_pcall(lstate, 0, 1);
208   if (*status) {
209     return true;  // break on error, but keep error on stack
210   }
211   *callback_result = lua_toboolean(lstate, -1);
212   lua_pop(lstate, 1);
213   return *callback_result;  // break if true
214 }
215 
216 /// "vim.wait(timeout, condition[, interval])" function
nlua_wait(lua_State * lstate)217 static int nlua_wait(lua_State *lstate)
218   FUNC_ATTR_NONNULL_ALL
219 {
220   intptr_t timeout = luaL_checkinteger(lstate, 1);
221   if (timeout < 0) {
222     return luaL_error(lstate, "timeout must be > 0");
223   }
224 
225   int lua_top = lua_gettop(lstate);
226 
227   // Check if condition can be called.
228   bool is_function = false;
229   if (lua_top >= 2 && !lua_isnil(lstate, 2)) {
230     is_function = (lua_type(lstate, 2) == LUA_TFUNCTION);
231 
232     // Check if condition is callable table
233     if (!is_function && luaL_getmetafield(lstate, 2, "__call") != 0) {
234       is_function = (lua_type(lstate, -1) == LUA_TFUNCTION);
235       lua_pop(lstate, 1);
236     }
237 
238     if (!is_function) {
239       lua_pushliteral(lstate,
240                       "vim.wait: if passed, condition must be a function");
241       return lua_error(lstate);
242     }
243   }
244 
245   intptr_t interval = 200;
246   if (lua_top >= 3 && !lua_isnil(lstate, 3)) {
247     interval = luaL_checkinteger(lstate, 3);
248     if (interval < 0) {
249       return luaL_error(lstate, "interval must be > 0");
250     }
251   }
252 
253   bool fast_only = false;
254   if (lua_top >= 4) {
255     fast_only =  lua_toboolean(lstate, 4);
256   }
257 
258   MultiQueue *loop_events = fast_only || in_fast_callback > 0
259     ? main_loop.fast_events : main_loop.events;
260 
261   TimeWatcher *tw = xmalloc(sizeof(TimeWatcher));
262 
263   // Start dummy timer.
264   time_watcher_init(&main_loop, tw, NULL);
265   tw->events = loop_events;
266   tw->blockable = true;
267   time_watcher_start(tw,
268                      dummy_timer_due_cb,
269                      (uint64_t)interval,
270                      (uint64_t)interval);
271 
272   int pcall_status = 0;
273   bool callback_result = false;
274 
275   LOOP_PROCESS_EVENTS_UNTIL(&main_loop,
276                             loop_events,
277                             (int)timeout,
278                             is_function ? nlua_wait_condition(lstate,
279                                                               &pcall_status,
280                                                               &callback_result) : false || got_int);
281 
282   // Stop dummy timer
283   time_watcher_stop(tw);
284   time_watcher_close(tw, dummy_timer_close_cb);
285 
286   if (pcall_status) {
287     return lua_error(lstate);
288   } else if (callback_result) {
289     lua_pushboolean(lstate, 1);
290     lua_pushnil(lstate);
291   } else if (got_int) {
292     got_int = false;
293     vgetc();
294     lua_pushboolean(lstate, 0);
295     lua_pushinteger(lstate, -2);
296   } else {
297     lua_pushboolean(lstate, 0);
298     lua_pushinteger(lstate, -1);
299   }
300 
301   return 2;
302 }
303 
304 /// Initialize lua interpreter state
305 ///
306 /// Called by lua interpreter itself to initialize state.
nlua_state_init(lua_State * const lstate)307 static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
308 {
309   // print
310   lua_pushcfunction(lstate, &nlua_print);
311   lua_setglobal(lstate, "print");
312 
313   // debug.debug
314   lua_getglobal(lstate, "debug");
315   lua_pushcfunction(lstate, &nlua_debug);
316   lua_setfield(lstate, -2, "debug");
317   lua_pop(lstate, 1);
318 
319 #ifdef WIN32
320   // os.getenv
321   lua_getglobal(lstate, "os");
322   lua_pushcfunction(lstate, &nlua_getenv);
323   lua_setfield(lstate, -2, "getenv");
324   lua_pop(lstate, 1);
325 #endif
326 
327   // vim
328   lua_newtable(lstate);
329 
330   // vim.api
331   nlua_add_api_functions(lstate);
332 
333   // vim.types, vim.type_idx, vim.val_idx
334   nlua_init_types(lstate);
335 
336   // neovim version
337   lua_pushcfunction(lstate, &nlua_nvim_version);
338   lua_setfield(lstate, -2, "version");
339 
340   // schedule
341   lua_pushcfunction(lstate, &nlua_schedule);
342   lua_setfield(lstate, -2, "schedule");
343 
344   // in_fast_event
345   lua_pushcfunction(lstate, &nlua_in_fast_event);
346   lua_setfield(lstate, -2, "in_fast_event");
347 
348   // call
349   lua_pushcfunction(lstate, &nlua_call);
350   lua_setfield(lstate, -2, "call");
351 
352   // rpcrequest
353   lua_pushcfunction(lstate, &nlua_rpcrequest);
354   lua_setfield(lstate, -2, "rpcrequest");
355 
356   // rpcnotify
357   lua_pushcfunction(lstate, &nlua_rpcnotify);
358   lua_setfield(lstate, -2, "rpcnotify");
359 
360   // wait
361   lua_pushcfunction(lstate, &nlua_wait);
362   lua_setfield(lstate, -2, "wait");
363 
364   // vim.NIL
365   lua_newuserdata(lstate, 0);
366   lua_createtable(lstate, 0, 0);
367   lua_pushcfunction(lstate, &nlua_nil_tostring);
368   lua_setfield(lstate, -2, "__tostring");
369   lua_setmetatable(lstate, -2);
370   nlua_nil_ref = nlua_ref(lstate, -1);
371   lua_pushvalue(lstate, -1);
372   lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.NIL");
373   lua_setfield(lstate, -2, "NIL");
374 
375   // vim._empty_dict_mt
376   lua_createtable(lstate, 0, 0);
377   lua_pushcfunction(lstate, &nlua_empty_dict_tostring);
378   lua_setfield(lstate, -2, "__tostring");
379   nlua_empty_dict_ref = nlua_ref(lstate, -1);
380   lua_pushvalue(lstate, -1);
381   lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.empty_dict");
382   lua_setfield(lstate, -2, "_empty_dict_mt");
383 
384   // internal vim._treesitter... API
385   nlua_add_treesitter(lstate);
386 
387   // vim.loop
388   luv_set_loop(lstate, &main_loop.uv);
389   luv_set_callback(lstate, nlua_luv_cfpcall);
390   luaopen_luv(lstate);
391   lua_pushvalue(lstate, -1);
392   lua_setfield(lstate, -3, "loop");
393 
394   // package.loaded.luv = vim.loop
395   // otherwise luv will be reinitialized when require'luv'
396   lua_getglobal(lstate, "package");
397   lua_getfield(lstate, -1, "loaded");
398   lua_pushvalue(lstate, -3);
399   lua_setfield(lstate, -2, "luv");
400   lua_pop(lstate, 3);
401 
402   nlua_state_add_stdlib(lstate);
403 
404   lua_setglobal(lstate, "vim");
405 
406   {
407     const char *code = (char *)&shared_module[0];
408     if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/shared.lua")
409         || nlua_pcall(lstate, 0, 0)) {
410       nlua_error(lstate, _("E5106: Error while creating shared module: %.*s"));
411       return 1;
412     }
413   }
414 
415   {
416     lua_getglobal(lstate, "package");  // [package]
417     lua_getfield(lstate, -1, "loaded");  // [package, loaded]
418 
419     const char *code = (char *)&inspect_module[0];
420     if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/inspect.lua")
421         || nlua_pcall(lstate, 0, 1)) {
422       nlua_error(lstate, _("E5106: Error while creating inspect module: %.*s"));
423       return 1;
424     }
425     // [package, loaded, inspect]
426     lua_setfield(lstate, -2, "vim.inspect");  // [package, loaded]
427 
428     code = (char *)&lua_F_module[0];
429     if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/F.lua")
430         || nlua_pcall(lstate, 0, 1)) {
431       nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s"));
432       return 1;
433     }
434     // [package, loaded, module]
435     lua_setfield(lstate, -2, "vim.F");  // [package, loaded]
436 
437     lua_pop(lstate, 2);  // []
438   }
439 
440   {
441     const char *code = (char *)&vim_module[0];
442     if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua")
443         || nlua_pcall(lstate, 0, 0)) {
444       nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
445       return 1;
446     }
447   }
448 
449   {
450     lua_getglobal(lstate, "package");  // [package]
451     lua_getfield(lstate, -1, "loaded");  // [package, loaded]
452 
453     const char *code = (char *)&lua_meta_module[0];
454     if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/_meta.lua")
455         || nlua_pcall(lstate, 0, 1)) {
456       nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s"));
457       return 1;
458     }
459     // [package, loaded, module]
460     lua_setfield(lstate, -2, "vim._meta");  // [package, loaded]
461 
462     lua_pop(lstate, 2);  // []
463   }
464 
465   return 0;
466 }
467 
468 /// Initialize global lua interpreter
469 ///
470 /// Crashes Nvim if initialization fails.
nlua_init(void)471 void nlua_init(void)
472 {
473 #ifdef NLUA_TRACK_REFS
474   const char *env = os_getenv("NVIM_LUA_NOTRACK");
475   if (!env || !*env) {
476     nlua_track_refs = true;
477   }
478 #endif
479 
480   lua_State *lstate = luaL_newstate();
481   if (lstate == NULL) {
482     emsg(_("E970: Failed to initialize lua interpreter"));
483     preserve_exit();
484   }
485   luaL_openlibs(lstate);
486   nlua_state_init(lstate);
487 
488   global_lstate = lstate;
489 }
490 
491 
nlua_free_all_mem(void)492 void nlua_free_all_mem(void)
493 {
494   if (!global_lstate) {
495     return;
496   }
497   lua_State *lstate = global_lstate;
498 
499   nlua_unref(lstate, nlua_nil_ref);
500   nlua_unref(lstate, nlua_empty_dict_ref);
501 
502 #ifdef NLUA_TRACK_REFS
503   if (nlua_refcount) {
504     fprintf(stderr, "%d lua references were leaked!", nlua_refcount);
505   }
506 
507   if (nlua_track_refs) {
508     // in case there are leaked luarefs, leak the associated memory
509     // to get LeakSanitizer stacktraces on exit
510     pmap_destroy(handle_T)(&nlua_ref_markers);
511   }
512 #endif
513 
514   nlua_refcount = 0;
515   lua_close(lstate);
516 }
517 
nlua_print_event(void ** argv)518 static void nlua_print_event(void **argv)
519 {
520   char *str = argv[0];
521   const size_t len = (size_t)(intptr_t)argv[1]-1;  // exclude final NUL
522 
523   for (size_t i = 0; i < len;) {
524     const size_t start = i;
525     while (i < len) {
526       switch (str[i]) {
527       case NUL:
528         str[i] = NL;
529         i++;
530         continue;
531       case NL:
532         // TODO(bfredl): use proper multiline msg? Probably should implement
533         // print() in lua in terms of nvim_message(), when it is available.
534         str[i] = NUL;
535         i++;
536         break;
537       default:
538         i++;
539         continue;
540       }
541       break;
542     }
543     msg(str + start);
544   }
545   if (len && str[len - 1] == NUL) {  // Last was newline
546     msg("");
547   }
548   xfree(str);
549 }
550 
551 /// Print as a Vim message
552 ///
553 /// @param  lstate  Lua interpreter state.
nlua_print(lua_State * const lstate)554 static int nlua_print(lua_State *const lstate)
555   FUNC_ATTR_NONNULL_ALL
556 {
557 #define PRINT_ERROR(msg) \
558   do { \
559     errmsg = msg; \
560     errmsg_len = sizeof(msg) - 1; \
561     goto nlua_print_error; \
562   } while (0)
563   const int nargs = lua_gettop(lstate);
564   lua_getglobal(lstate, "tostring");
565   const char *errmsg = NULL;
566   size_t errmsg_len = 0;
567   garray_T msg_ga;
568   ga_init(&msg_ga, 1, 80);
569   int curargidx = 1;
570   for (; curargidx <= nargs; curargidx++) {
571     lua_pushvalue(lstate, -1);  // tostring
572     lua_pushvalue(lstate, curargidx);  // arg
573     // Do not use nlua_pcall here to avoid duplicate stack trace information
574     if (lua_pcall(lstate, 1, 1, 0)) {
575       errmsg = lua_tolstring(lstate, -1, &errmsg_len);
576       goto nlua_print_error;
577     }
578     size_t len;
579     const char *const s = lua_tolstring(lstate, -1, &len);
580     if (s == NULL) {
581       PRINT_ERROR("<Unknown error: lua_tolstring returned NULL for tostring result>");
582     }
583     ga_concat_len(&msg_ga, s, len);
584     if (curargidx < nargs) {
585       ga_append(&msg_ga, ' ');
586     }
587     lua_pop(lstate, 1);
588   }
589 #undef PRINT_ERROR
590   ga_append(&msg_ga, NUL);
591 
592   if (in_fast_callback) {
593     multiqueue_put(main_loop.events, nlua_print_event,
594                    2, msg_ga.ga_data, msg_ga.ga_len);
595   } else {
596     nlua_print_event((void *[]){ msg_ga.ga_data,
597                                  (void *)(intptr_t)msg_ga.ga_len });
598   }
599   return 0;
600 
601 nlua_print_error:
602   ga_clear(&msg_ga);
603   const char *fmt = _("E5114: Error while converting print argument #%i: %.*s");
604   size_t len = (size_t)vim_snprintf((char *)IObuff, IOSIZE, fmt, curargidx,
605                                     (int)errmsg_len, errmsg);
606   lua_pushlstring(lstate, (char *)IObuff, len);
607   return lua_error(lstate);
608 }
609 
610 /// debug.debug: interaction with user while debugging.
611 ///
612 /// @param  lstate  Lua interpreter state.
nlua_debug(lua_State * lstate)613 static int nlua_debug(lua_State *lstate)
614   FUNC_ATTR_NONNULL_ALL
615 {
616   const typval_T input_args[] = {
617     {
618       .v_lock = VAR_FIXED,
619       .v_type = VAR_STRING,
620       .vval.v_string = (char_u *)"lua_debug> ",
621     },
622     {
623       .v_type = VAR_UNKNOWN,
624     },
625   };
626   for (;;) {
627     lua_settop(lstate, 0);
628     typval_T input;
629     get_user_input(input_args, &input, false, false);
630     msg_putchar('\n');  // Avoid outputting on input line.
631     if (input.v_type != VAR_STRING
632         || input.vval.v_string == NULL
633         || *input.vval.v_string == NUL
634         || STRCMP(input.vval.v_string, "cont") == 0) {
635       tv_clear(&input);
636       return 0;
637     }
638     if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
639                         STRLEN(input.vval.v_string), "=(debug command)")) {
640       nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
641     } else if (nlua_pcall(lstate, 0, 0)) {
642       nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
643     }
644     tv_clear(&input);
645   }
646   return 0;
647 }
648 
nlua_in_fast_event(lua_State * lstate)649 int nlua_in_fast_event(lua_State *lstate)
650 {
651   lua_pushboolean(lstate, in_fast_callback > 0);
652   return 1;
653 }
654 
nlua_call(lua_State * lstate)655 int nlua_call(lua_State *lstate)
656 {
657   Error err = ERROR_INIT;
658   size_t name_len;
659   const char_u *name = (const char_u *)luaL_checklstring(lstate, 1, &name_len);
660   if (!nlua_is_deferred_safe()) {
661     return luaL_error(lstate, e_luv_api_disabled, "vimL function");
662   }
663 
664   int nargs = lua_gettop(lstate)-1;
665   if (nargs > MAX_FUNC_ARGS) {
666     return luaL_error(lstate, "Function called with too many arguments");
667   }
668 
669   typval_T vim_args[MAX_FUNC_ARGS + 1];
670   int i = 0;  // also used for freeing the variables
671   for (; i < nargs; i++) {
672     lua_pushvalue(lstate, (int)i+2);
673     if (!nlua_pop_typval(lstate, &vim_args[i])) {
674       api_set_error(&err, kErrorTypeException,
675                     "error converting argument %d", i+1);
676       goto free_vim_args;
677     }
678   }
679 
680   TRY_WRAP({
681     // TODO(bfredl): this should be simplified in error handling refactor
682     force_abort = false;
683     suppress_errthrow = false;
684     current_exception = NULL;
685     did_emsg = false;
686 
687     try_start();
688     typval_T rettv;
689     funcexe_T funcexe = FUNCEXE_INIT;
690     funcexe.firstline = curwin->w_cursor.lnum;
691     funcexe.lastline = curwin->w_cursor.lnum;
692     funcexe.evaluate = true;
693     // call_func() retval is deceptive, ignore it.  Instead we set `msg_list`
694     // (TRY_WRAP) to capture abort-causing non-exception errors.
695     (void)call_func(name, (int)name_len, &rettv, nargs, vim_args, &funcexe);
696     if (!try_end(&err)) {
697       nlua_push_typval(lstate, &rettv, false);
698     }
699     tv_clear(&rettv);
700   });
701 
702 free_vim_args:
703   while (i > 0) {
704     tv_clear(&vim_args[--i]);
705   }
706   if (ERROR_SET(&err)) {
707     lua_pushstring(lstate, err.msg);
708     api_clear_error(&err);
709     return lua_error(lstate);
710   }
711   return 1;
712 }
713 
nlua_rpcrequest(lua_State * lstate)714 static int nlua_rpcrequest(lua_State *lstate)
715 {
716   if (!nlua_is_deferred_safe()) {
717     return luaL_error(lstate, e_luv_api_disabled, "rpcrequest");
718   }
719   return nlua_rpc(lstate, true);
720 }
721 
nlua_rpcnotify(lua_State * lstate)722 static int nlua_rpcnotify(lua_State *lstate)
723 {
724   return nlua_rpc(lstate, false);
725 }
726 
nlua_rpc(lua_State * lstate,bool request)727 static int nlua_rpc(lua_State *lstate, bool request)
728 {
729   size_t name_len;
730   uint64_t chan_id = (uint64_t)luaL_checkinteger(lstate, 1);
731   const char *name = luaL_checklstring(lstate, 2, &name_len);
732   int nargs = lua_gettop(lstate)-2;
733   Error err = ERROR_INIT;
734   Array args = ARRAY_DICT_INIT;
735 
736   for (int i = 0; i < nargs; i++) {
737     lua_pushvalue(lstate, (int)i+3);
738     ADD(args, nlua_pop_Object(lstate, false, &err));
739     if (ERROR_SET(&err)) {
740       api_free_array(args);
741       goto check_err;
742     }
743   }
744 
745   if (request) {
746     Object result = rpc_send_call(chan_id, name, args, &err);
747     if (!ERROR_SET(&err)) {
748       nlua_push_Object(lstate, result, false);
749       api_free_object(result);
750     }
751   } else {
752     if (!rpc_send_event(chan_id, name, args)) {
753       api_set_error(&err, kErrorTypeValidation,
754                     "Invalid channel: %" PRIu64, chan_id);
755     }
756   }
757 
758 check_err:
759   if (ERROR_SET(&err)) {
760     lua_pushstring(lstate, err.msg);
761     api_clear_error(&err);
762     return lua_error(lstate);
763   }
764 
765   return request ? 1 : 0;
766 }
767 
nlua_nil_tostring(lua_State * lstate)768 static int nlua_nil_tostring(lua_State *lstate)
769 {
770   lua_pushstring(lstate, "vim.NIL");
771   return 1;
772 }
773 
nlua_empty_dict_tostring(lua_State * lstate)774 static int nlua_empty_dict_tostring(lua_State *lstate)
775 {
776   lua_pushstring(lstate, "vim.empty_dict()");
777   return 1;
778 }
779 
780 
781 #ifdef WIN32
782 /// os.getenv: override os.getenv to maintain coherency. #9681
783 ///
784 /// uv_os_setenv uses SetEnvironmentVariableW which does not update _environ.
785 ///
786 /// @param  lstate  Lua interpreter state.
nlua_getenv(lua_State * lstate)787 static int nlua_getenv(lua_State *lstate)
788 {
789   lua_pushstring(lstate, os_getenv(luaL_checkstring(lstate, 1)));
790   return 1;
791 }
792 #endif
793 
794 
795 /// add the value to the registry
nlua_ref(lua_State * lstate,int index)796 LuaRef nlua_ref(lua_State *lstate, int index)
797 {
798   lua_pushvalue(lstate, index);
799   LuaRef ref = luaL_ref(lstate, LUA_REGISTRYINDEX);
800   if (ref > 0) {
801     nlua_refcount++;
802 #ifdef NLUA_TRACK_REFS
803     if (nlua_track_refs) {
804       // dummy allocation to make LeakSanitizer track our luarefs
805       pmap_put(handle_T)(&nlua_ref_markers, ref, xmalloc(3));
806     }
807 #endif
808   }
809   return ref;
810 }
811 
812 /// remove the value from the registry
nlua_unref(lua_State * lstate,LuaRef ref)813 void nlua_unref(lua_State *lstate, LuaRef ref)
814 {
815   if (ref > 0) {
816     nlua_refcount--;
817 #ifdef NLUA_TRACK_REFS
818     // NB: don't remove entry from map to track double-unref
819     if (nlua_track_refs) {
820       xfree(pmap_get(handle_T)(&nlua_ref_markers, ref));
821     }
822 #endif
823     luaL_unref(lstate, LUA_REGISTRYINDEX, ref);
824   }
825 }
826 
api_free_luaref(LuaRef ref)827 void api_free_luaref(LuaRef ref)
828 {
829   nlua_unref(global_lstate, ref);
830 }
831 
832 /// push a value referenced in the registry
nlua_pushref(lua_State * lstate,LuaRef ref)833 void nlua_pushref(lua_State *lstate, LuaRef ref)
834 {
835   lua_rawgeti(lstate, LUA_REGISTRYINDEX, ref);
836 }
837 
838 
839 /// Gets a new reference to an object stored at original_ref
840 ///
841 /// NOTE: It does not copy the value, it creates a new ref to the lua object.
842 ///       Leaves the stack unchanged.
api_new_luaref(LuaRef original_ref)843 LuaRef api_new_luaref(LuaRef original_ref)
844 {
845   if (original_ref == LUA_NOREF) {
846     return LUA_NOREF;
847   }
848 
849   lua_State *const lstate = global_lstate;
850   nlua_pushref(lstate, original_ref);
851   LuaRef new_ref = nlua_ref(lstate, -1);
852   lua_pop(lstate, 1);
853   return new_ref;
854 }
855 
856 
857 /// Evaluate lua string
858 ///
859 /// Used for luaeval().
860 ///
861 /// @param[in]  str  String to execute.
862 /// @param[in]  arg  Second argument to `luaeval()`.
863 /// @param[out]  ret_tv  Location where result will be saved.
864 ///
865 /// @return Result of the execution.
nlua_typval_eval(const String str,typval_T * const arg,typval_T * const ret_tv)866 void nlua_typval_eval(const String str, typval_T *const arg, typval_T *const ret_tv)
867   FUNC_ATTR_NONNULL_ALL
868 {
869 #define EVALHEADER "local _A=select(1,...) return ("
870   const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1;
871   char *lcmd;
872   if (lcmd_len < IOSIZE) {
873     lcmd = (char *)IObuff;
874   } else {
875     lcmd = xmalloc(lcmd_len);
876   }
877   memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
878   memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
879   lcmd[lcmd_len - 1] = ')';
880 #undef EVALHEADER
881   nlua_typval_exec(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv);
882 
883   if (lcmd != (char *)IObuff) {
884     xfree(lcmd);
885   }
886 }
887 
nlua_typval_call(const char * str,size_t len,typval_T * const args,int argcount,typval_T * ret_tv)888 void nlua_typval_call(const char *str, size_t len, typval_T *const args, int argcount,
889                       typval_T *ret_tv)
890   FUNC_ATTR_NONNULL_ALL
891 {
892 #define CALLHEADER "return "
893 #define CALLSUFFIX "(...)"
894   const size_t lcmd_len = sizeof(CALLHEADER) - 1 + len + sizeof(CALLSUFFIX) - 1;
895   char *lcmd;
896   if (lcmd_len < IOSIZE) {
897     lcmd = (char *)IObuff;
898   } else {
899     lcmd = xmalloc(lcmd_len);
900   }
901   memcpy(lcmd, CALLHEADER, sizeof(CALLHEADER) - 1);
902   memcpy(lcmd + sizeof(CALLHEADER) - 1, str, len);
903   memcpy(lcmd + sizeof(CALLHEADER) - 1 + len, CALLSUFFIX,
904          sizeof(CALLSUFFIX) - 1);
905 #undef CALLHEADER
906 #undef CALLSUFFIX
907 
908   nlua_typval_exec(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv);
909 
910   if (lcmd != (char *)IObuff) {
911     xfree(lcmd);
912   }
913 }
914 
nlua_typval_exec(const char * lcmd,size_t lcmd_len,const char * name,typval_T * const args,int argcount,bool special,typval_T * ret_tv)915 static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name,
916                              typval_T *const args, int argcount, bool special, typval_T *ret_tv)
917 {
918   if (check_secure()) {
919     if (ret_tv) {
920       ret_tv->v_type = VAR_NUMBER;
921       ret_tv->vval.v_number = 0;
922     }
923     return;
924   }
925 
926   lua_State *const lstate = global_lstate;
927   if (luaL_loadbuffer(lstate, lcmd, lcmd_len, name)) {
928     nlua_error(lstate, _("E5107: Error loading lua %.*s"));
929     return;
930   }
931 
932   PUSH_ALL_TYPVALS(lstate, args, argcount, special);
933 
934   if (nlua_pcall(lstate, argcount, ret_tv ? 1 : 0)) {
935     nlua_error(lstate, _("E5108: Error executing lua %.*s"));
936     return;
937   }
938 
939   if (ret_tv) {
940     nlua_pop_typval(lstate, ret_tv);
941   }
942 }
943 
nlua_source_using_linegetter(LineGetter fgetline,void * cookie,char * name)944 int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name)
945 {
946   const linenr_T save_sourcing_lnum = sourcing_lnum;
947   const sctx_T save_current_sctx = current_sctx;
948   current_sctx.sc_sid = SID_STR;
949   current_sctx.sc_seq = 0;
950   current_sctx.sc_lnum = 0;
951   sourcing_lnum = 0;
952 
953   garray_T ga;
954   char_u *line = NULL;
955 
956   ga_init(&ga, (int)sizeof(char_u *), 10);
957   while ((line = fgetline(0, cookie, 0, false)) != NULL) {
958     GA_APPEND(char_u *, &ga, line);
959   }
960   char *code = ga_concat_strings_sep(&ga, "\n");
961   size_t len = strlen(code);
962   nlua_typval_exec(code, len, name, NULL, 0, false, NULL);
963 
964   sourcing_lnum = save_sourcing_lnum;
965   current_sctx = save_current_sctx;
966   ga_clear_strings(&ga);
967   xfree(code);
968   return OK;
969 }
970 
971 /// Call a LuaCallable given some typvals
972 ///
973 /// Used to call any lua callable passed from Lua into VimL
974 ///
975 /// @param[in]  lstate Lua State
976 /// @param[in]  lua_cb Lua Callable
977 /// @param[in]  argcount Count of typval arguments
978 /// @param[in]  argvars Typval Arguments
979 /// @param[out] rettv The return value from the called function.
typval_exec_lua_callable(lua_State * lstate,LuaCallable lua_cb,int argcount,typval_T * argvars,typval_T * rettv)980 int typval_exec_lua_callable(lua_State *lstate, LuaCallable lua_cb, int argcount, typval_T *argvars,
981                              typval_T *rettv)
982 {
983   LuaRef cb = lua_cb.func_ref;
984 
985   nlua_pushref(lstate, cb);
986 
987   PUSH_ALL_TYPVALS(lstate, argvars, argcount, false);
988 
989   if (nlua_pcall(lstate, argcount, 1)) {
990     nlua_print(lstate);
991     return ERROR_OTHER;
992   }
993 
994   nlua_pop_typval(lstate, rettv);
995 
996   return ERROR_NONE;
997 }
998 
999 /// Execute Lua string
1000 ///
1001 /// Used for nvim_exec_lua() and internally to execute a lua string.
1002 ///
1003 /// @param[in]  str  String to execute.
1004 /// @param[in]  args array of ... args
1005 /// @param[out]  err  Location where error will be saved.
1006 ///
1007 /// @return Return value of the execution.
nlua_exec(const String str,const Array args,Error * err)1008 Object nlua_exec(const String str, const Array args, Error *err)
1009 {
1010   lua_State *const lstate = global_lstate;
1011 
1012   if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
1013     size_t len;
1014     const char *errstr = lua_tolstring(lstate, -1, &len);
1015     api_set_error(err, kErrorTypeValidation,
1016                   "Error loading lua: %.*s", (int)len, errstr);
1017     return NIL;
1018   }
1019 
1020   for (size_t i = 0; i < args.size; i++) {
1021     nlua_push_Object(lstate, args.items[i], false);
1022   }
1023 
1024   if (nlua_pcall(lstate, (int)args.size, 1)) {
1025     size_t len;
1026     const char *errstr = lua_tolstring(lstate, -1, &len);
1027     api_set_error(err, kErrorTypeException,
1028                   "Error executing lua: %.*s", (int)len, errstr);
1029     return NIL;
1030   }
1031 
1032   return nlua_pop_Object(lstate, false, err);
1033 }
1034 
1035 /// call a LuaRef as a function (or table with __call metamethod)
1036 ///
1037 /// @param ref     the reference to call (not consumed)
1038 /// @param name    if non-NULL, sent to callback as first arg
1039 ///                if NULL, only args are used
1040 /// @param retval  if true, convert return value to Object
1041 ///                if false, discard return value
1042 /// @param err     Error details, if any (if NULL, errors are echoed)
1043 /// @return        Return value of function, if retval was set. Otherwise NIL.
nlua_call_ref(LuaRef ref,const char * name,Array args,bool retval,Error * err)1044 Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Error *err)
1045 {
1046   lua_State *const lstate = global_lstate;
1047   nlua_pushref(lstate, ref);
1048   int nargs = (int)args.size;
1049   if (name != NULL) {
1050     lua_pushstring(lstate, name);
1051     nargs++;
1052   }
1053   for (size_t i = 0; i < args.size; i++) {
1054     nlua_push_Object(lstate, args.items[i], false);
1055   }
1056 
1057   if (nlua_pcall(lstate, nargs, retval ? 1 : 0)) {
1058     // if err is passed, the caller will deal with the error.
1059     if (err) {
1060       size_t len;
1061       const char *errstr = lua_tolstring(lstate, -1, &len);
1062       api_set_error(err, kErrorTypeException,
1063                     "Error executing lua: %.*s", (int)len, errstr);
1064     } else {
1065       nlua_error(lstate, _("Error executing lua callback: %.*s"));
1066     }
1067     return NIL;
1068   }
1069 
1070   if (retval) {
1071     Error dummy = ERROR_INIT;
1072     if (err == NULL) {
1073       err = &dummy;
1074     }
1075     return nlua_pop_Object(lstate, false, err);
1076   } else {
1077     return NIL;
1078   }
1079 }
1080 
1081 /// check if the current execution context is safe for calling deferred API
1082 /// methods. Luv callbacks are unsafe as they are called inside the uv loop.
nlua_is_deferred_safe(void)1083 bool nlua_is_deferred_safe(void)
1084 {
1085   return in_fast_callback == 0;
1086 }
1087 
1088 /// Run lua string
1089 ///
1090 /// Used for :lua.
1091 ///
1092 /// @param  eap  VimL command being run.
ex_lua(exarg_T * const eap)1093 void ex_lua(exarg_T *const eap)
1094   FUNC_ATTR_NONNULL_ALL
1095 {
1096   size_t len;
1097   char *const code = script_get(eap, &len);
1098   if (eap->skip) {
1099     xfree(code);
1100     return;
1101   }
1102   nlua_typval_exec(code, len, ":lua", NULL, 0, false, NULL);
1103 
1104   xfree(code);
1105 }
1106 
1107 /// Run lua string for each line in range
1108 ///
1109 /// Used for :luado.
1110 ///
1111 /// @param  eap  VimL command being run.
ex_luado(exarg_T * const eap)1112 void ex_luado(exarg_T *const eap)
1113   FUNC_ATTR_NONNULL_ALL
1114 {
1115   if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
1116     emsg(_("cannot save undo information"));
1117     return;
1118   }
1119   const char *const cmd = (const char *)eap->arg;
1120   const size_t cmd_len = strlen(cmd);
1121 
1122   lua_State *const lstate = global_lstate;
1123 
1124 #define DOSTART "return function(line, linenr) "
1125 #define DOEND " end"
1126   const size_t lcmd_len = (cmd_len
1127                            + (sizeof(DOSTART) - 1)
1128                            + (sizeof(DOEND) - 1));
1129   char *lcmd;
1130   if (lcmd_len < IOSIZE) {
1131     lcmd = (char *)IObuff;
1132   } else {
1133     lcmd = xmalloc(lcmd_len + 1);
1134   }
1135   memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
1136   memcpy(lcmd + sizeof(DOSTART) - 1, cmd, cmd_len);
1137   memcpy(lcmd + sizeof(DOSTART) - 1 + cmd_len, DOEND, sizeof(DOEND) - 1);
1138 #undef DOSTART
1139 #undef DOEND
1140 
1141   if (luaL_loadbuffer(lstate, lcmd, lcmd_len, ":luado")) {
1142     nlua_error(lstate, _("E5109: Error loading lua: %.*s"));
1143     if (lcmd_len >= IOSIZE) {
1144       xfree(lcmd);
1145     }
1146     return;
1147   }
1148   if (lcmd_len >= IOSIZE) {
1149     xfree(lcmd);
1150   }
1151   if (nlua_pcall(lstate, 0, 1)) {
1152     nlua_error(lstate, _("E5110: Error executing lua: %.*s"));
1153     return;
1154   }
1155   for (linenr_T l = eap->line1; l <= eap->line2; l++) {
1156     if (l > curbuf->b_ml.ml_line_count) {
1157       break;
1158     }
1159     lua_pushvalue(lstate, -1);
1160     const char *old_line = (const char *)ml_get_buf(curbuf, l, false);
1161     lua_pushstring(lstate, old_line);
1162     lua_pushnumber(lstate, (lua_Number)l);
1163     if (nlua_pcall(lstate, 2, 1)) {
1164       nlua_error(lstate, _("E5111: Error calling lua: %.*s"));
1165       break;
1166     }
1167     if (lua_isstring(lstate, -1)) {
1168       size_t old_line_len = STRLEN(old_line);
1169 
1170       size_t new_line_len;
1171       const char *const new_line = lua_tolstring(lstate, -1, &new_line_len);
1172       char *const new_line_transformed = xmemdupz(new_line, new_line_len);
1173       for (size_t i = 0; i < new_line_len; i++) {
1174         if (new_line_transformed[i] == NUL) {
1175           new_line_transformed[i] = '\n';
1176         }
1177       }
1178       ml_replace(l, (char_u *)new_line_transformed, false);
1179       inserted_bytes(l, 0, (int)old_line_len, (int)new_line_len);
1180     }
1181     lua_pop(lstate, 1);
1182   }
1183   lua_pop(lstate, 1);
1184   check_cursor();
1185   update_screen(NOT_VALID);
1186 }
1187 
1188 /// Run lua file
1189 ///
1190 /// Used for :luafile.
1191 ///
1192 /// @param  eap  VimL command being run.
ex_luafile(exarg_T * const eap)1193 void ex_luafile(exarg_T *const eap)
1194   FUNC_ATTR_NONNULL_ALL
1195 {
1196   nlua_exec_file((const char *)eap->arg);
1197 }
1198 
1199 /// execute lua code from a file.
1200 ///
1201 /// @param  path  path of the file
1202 ///
1203 /// @return  true if everything ok, false if there was an error (echoed)
nlua_exec_file(const char * path)1204 bool nlua_exec_file(const char *path)
1205   FUNC_ATTR_NONNULL_ALL
1206 {
1207   lua_State *const lstate = global_lstate;
1208 
1209   if (luaL_loadfile(lstate, path)) {
1210     nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
1211     return false;
1212   }
1213 
1214   if (nlua_pcall(lstate, 0, 0)) {
1215     nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
1216     return false;
1217   }
1218 
1219   return true;
1220 }
1221 
tslua_get_language_version(lua_State * L)1222 int tslua_get_language_version(lua_State *L)
1223 {
1224   lua_pushnumber(L, TREE_SITTER_LANGUAGE_VERSION);
1225   return 1;
1226 }
1227 
nlua_add_treesitter(lua_State * const lstate)1228 static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
1229 {
1230   tslua_init(lstate);
1231 
1232   lua_pushcfunction(lstate, tslua_push_parser);
1233   lua_setfield(lstate, -2, "_create_ts_parser");
1234 
1235   lua_pushcfunction(lstate, tslua_add_language);
1236   lua_setfield(lstate, -2, "_ts_add_language");
1237 
1238   lua_pushcfunction(lstate, tslua_has_language);
1239   lua_setfield(lstate, -2, "_ts_has_language");
1240 
1241   lua_pushcfunction(lstate, tslua_inspect_lang);
1242   lua_setfield(lstate, -2, "_ts_inspect_language");
1243 
1244   lua_pushcfunction(lstate, tslua_parse_query);
1245   lua_setfield(lstate, -2, "_ts_parse_query");
1246 
1247   lua_pushcfunction(lstate, tslua_get_language_version);
1248   lua_setfield(lstate, -2, "_ts_get_language_version");
1249 }
1250 
nlua_expand_pat(expand_T * xp,char_u * pat,int * num_results,char_u *** results)1251 int nlua_expand_pat(expand_T *xp, char_u *pat, int *num_results, char_u ***results)
1252 {
1253   lua_State *const lstate = global_lstate;
1254   int ret = OK;
1255 
1256   // [ vim ]
1257   lua_getglobal(lstate, "vim");
1258 
1259   // [ vim, vim._expand_pat ]
1260   lua_getfield(lstate, -1, "_expand_pat");
1261   luaL_checktype(lstate, -1, LUA_TFUNCTION);
1262 
1263   // [ vim, vim._on_key, buf ]
1264   lua_pushlstring(lstate, (const char *)pat, STRLEN(pat));
1265 
1266   if (nlua_pcall(lstate, 1, 2) != 0) {
1267     nlua_error(lstate,
1268                _("Error executing vim._expand_pat: %.*s"));
1269     return FAIL;
1270   }
1271 
1272   Error err = ERROR_INIT;
1273 
1274   *num_results = 0;
1275   *results = NULL;
1276 
1277   int prefix_len = (int)nlua_pop_Integer(lstate, &err);
1278   if (ERROR_SET(&err)) {
1279     ret = FAIL;
1280     goto cleanup;
1281   }
1282 
1283   Array completions = nlua_pop_Array(lstate, &err);
1284   if (ERROR_SET(&err)) {
1285     ret = FAIL;
1286     goto cleanup_array;
1287   }
1288 
1289   garray_T result_array;
1290   ga_init(&result_array, (int)sizeof(char *), 80);
1291   for (size_t i = 0; i < completions.size; i++) {
1292     Object v = completions.items[i];
1293 
1294     if (v.type != kObjectTypeString) {
1295       ret = FAIL;
1296       goto cleanup_array;
1297     }
1298 
1299     GA_APPEND(char_u *,
1300               &result_array,
1301               vim_strsave((char_u *)v.data.string.data));
1302   }
1303 
1304   xp->xp_pattern += prefix_len;
1305   *results = result_array.ga_data;
1306   *num_results = result_array.ga_len;
1307 
1308 cleanup_array:
1309   api_free_array(completions);
1310 
1311 cleanup:
1312 
1313   if (ret == FAIL) {
1314     ga_clear(&result_array);
1315   }
1316 
1317   return ret;
1318 }
1319 
1320 // Required functions for lua c functions as VimL callbacks
1321 
nlua_CFunction_func_call(int argcount,typval_T * argvars,typval_T * rettv,void * state)1322 int nlua_CFunction_func_call(int argcount, typval_T *argvars, typval_T *rettv, void *state)
1323 {
1324   lua_State *const lstate = global_lstate;
1325   LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
1326 
1327   return typval_exec_lua_callable(lstate, funcstate->lua_callable,
1328                                   argcount, argvars, rettv);
1329 }
1330 
nlua_CFunction_func_free(void * state)1331 void nlua_CFunction_func_free(void *state)
1332 {
1333   lua_State *const lstate = global_lstate;
1334   LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
1335 
1336   nlua_unref(lstate, funcstate->lua_callable.func_ref);
1337   xfree(funcstate);
1338 }
1339 
nlua_is_table_from_lua(typval_T * const arg)1340 bool nlua_is_table_from_lua(typval_T *const arg)
1341 {
1342   if (arg->v_type == VAR_DICT) {
1343     return arg->vval.v_dict->lua_table_ref != LUA_NOREF;
1344   } else if (arg->v_type == VAR_LIST) {
1345     return arg->vval.v_list->lua_table_ref != LUA_NOREF;
1346   } else {
1347     return false;
1348   }
1349 }
1350 
nlua_register_table_as_callable(typval_T * const arg)1351 char_u *nlua_register_table_as_callable(typval_T *const arg)
1352 {
1353   LuaRef table_ref = LUA_NOREF;
1354   if (arg->v_type == VAR_DICT) {
1355     table_ref = arg->vval.v_dict->lua_table_ref;
1356   } else if (arg->v_type == VAR_LIST) {
1357     table_ref = arg->vval.v_list->lua_table_ref;
1358   }
1359 
1360   if (table_ref == LUA_NOREF) {
1361     return NULL;
1362   }
1363 
1364   lua_State *const lstate = global_lstate;
1365 
1366 #ifndef NDEBUG
1367   int top = lua_gettop(lstate);
1368 #endif
1369 
1370   nlua_pushref(lstate, table_ref);  // [table]
1371   if (!lua_getmetatable(lstate, -1)) {
1372     lua_pop(lstate, 1);
1373     assert(top == lua_gettop(lstate));
1374     return NULL;
1375   }  // [table, mt]
1376 
1377   lua_getfield(lstate, -1, "__call");  // [table, mt, mt.__call]
1378   if (!lua_isfunction(lstate, -1)) {
1379     lua_pop(lstate, 3);
1380     assert(top == lua_gettop(lstate));
1381     return NULL;
1382   }
1383   lua_pop(lstate, 2);  // [table]
1384 
1385   LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState));
1386   state->lua_callable.func_ref = nlua_ref(lstate, -1);
1387 
1388   char_u *name = register_cfunc(&nlua_CFunction_func_call,
1389                                 &nlua_CFunction_func_free, state);
1390 
1391 
1392   lua_pop(lstate, 1);  // []
1393   assert(top == lua_gettop(lstate));
1394 
1395   return name;
1396 }
1397 
nlua_execute_on_key(int c)1398 void nlua_execute_on_key(int c)
1399 {
1400   char_u buf[NUMBUFLEN];
1401   size_t buf_len = special_to_buf(c, mod_mask, false, buf);
1402 
1403   lua_State *const lstate = global_lstate;
1404 
1405 #ifndef NDEBUG
1406   int top = lua_gettop(lstate);
1407 #endif
1408 
1409   // [ vim ]
1410   lua_getglobal(lstate, "vim");
1411 
1412   // [ vim, vim._on_key]
1413   lua_getfield(lstate, -1, "_on_key");
1414   luaL_checktype(lstate, -1, LUA_TFUNCTION);
1415 
1416   // [ vim, vim._on_key, buf ]
1417   lua_pushlstring(lstate, (const char *)buf, buf_len);
1418 
1419   if (nlua_pcall(lstate, 1, 0)) {
1420     nlua_error(lstate,
1421                _("Error executing  vim.on_key Lua callback: %.*s"));
1422   }
1423 
1424   // [ vim ]
1425   lua_pop(lstate, 1);
1426 
1427 #ifndef NDEBUG
1428   // [ ]
1429   assert(top == lua_gettop(lstate));
1430 #endif
1431 }
1432 
1433