aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua/executor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r--src/nvim/lua/executor.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 6120deb77a..b27b1ae7a8 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -85,6 +85,27 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
lua_pop(lstate, 1);
}
+/// Like lua_pcall, but use debug.traceback as errfunc.
+///
+/// @param lstate Lua interpreter state
+/// @param[in] nargs Number of arguments expected by the function being called.
+/// @param[in] nresults Number of results the function returns.
+static int nlua_pcall(lua_State *lstate, int nargs, int nresults)
+{
+ lua_getglobal(lstate, "debug");
+ lua_getfield(lstate, -1, "traceback");
+ lua_remove(lstate, -2);
+ lua_insert(lstate, -2 - nargs);
+ int status = lua_pcall(lstate, nargs, nresults, -2 - nargs);
+ if (status) {
+ lua_remove(lstate, -2);
+ } else {
+ lua_remove(lstate, -1 - nresults);
+ }
+ return status;
+}
+
+
/// Gets the version of the current Nvim build.
///
/// @param lstate Lua interpreter state.
@@ -115,7 +136,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags
in_fast_callback++;
int top = lua_gettop(lstate);
- int status = lua_pcall(lstate, nargs, nresult, 0);
+ int status = nlua_pcall(lstate, nargs, nresult);
if (status) {
if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) {
// consider out of memory errors unrecoverable, just like xmalloc()
@@ -146,7 +167,7 @@ static void nlua_schedule_event(void **argv)
lua_State *const lstate = global_lstate;
nlua_pushref(lstate, cb);
nlua_unref(lstate, cb);
- if (lua_pcall(lstate, 0, 0, 0)) {
+ if (nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("Error executing vim.schedule lua callback: %.*s"));
}
}
@@ -183,7 +204,7 @@ static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_result)
{
lua_pushvalue(lstate, 2);
- *status = lua_pcall(lstate, 0, 1, 0);
+ *status = nlua_pcall(lstate, 0, 1);
if (*status) {
return true; // break on error, but keep error on stack
}
@@ -385,7 +406,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
const char *code = (char *)&shared_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/shared.lua")
- || lua_pcall(lstate, 0, 0, 0)) {
+ || nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5106: Error while creating shared module: %.*s"));
return 1;
}
@@ -397,7 +418,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
const char *code = (char *)&inspect_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/inspect.lua")
- || lua_pcall(lstate, 0, 1, 0)) {
+ || nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5106: Error while creating inspect module: %.*s"));
return 1;
}
@@ -406,7 +427,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
code = (char *)&lua_F_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/F.lua")
- || lua_pcall(lstate, 0, 1, 0)) {
+ || nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s"));
return 1;
}
@@ -419,7 +440,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
const char *code = (char *)&vim_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua")
- || lua_pcall(lstate, 0, 0, 0)) {
+ || nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
return 1;
}
@@ -431,7 +452,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
const char *code = (char *)&lua_meta_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/_meta.lua")
- || lua_pcall(lstate, 0, 1, 0)) {
+ || nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s"));
return 1;
}
@@ -549,6 +570,7 @@ static int nlua_print(lua_State *const lstate)
for (; curargidx <= nargs; curargidx++) {
lua_pushvalue(lstate, -1); // tostring
lua_pushvalue(lstate, curargidx); // arg
+ // Do not use nlua_pcall here to avoid duplicate stack trace information
if (lua_pcall(lstate, 1, 1, 0)) {
errmsg = lua_tolstring(lstate, -1, &errmsg_len);
goto nlua_print_error;
@@ -616,7 +638,7 @@ static int nlua_debug(lua_State *lstate)
if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
STRLEN(input.vval.v_string), "=(debug command)")) {
nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
- } else if (lua_pcall(lstate, 0, 0, 0)) {
+ } else if (nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
}
tv_clear(&input);
@@ -909,7 +931,7 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name
PUSH_ALL_TYPVALS(lstate, args, argcount, special);
- if (lua_pcall(lstate, argcount, ret_tv ? 1 : 0, 0)) {
+ if (nlua_pcall(lstate, argcount, ret_tv ? 1 : 0)) {
nlua_error(lstate, _("E5108: Error executing lua %.*s"));
return;
}
@@ -964,7 +986,7 @@ int typval_exec_lua_callable(lua_State *lstate, LuaCallable lua_cb, int argcount
PUSH_ALL_TYPVALS(lstate, argvars, argcount, false);
- if (lua_pcall(lstate, argcount, 1, 0)) {
+ if (nlua_pcall(lstate, argcount, 1)) {
nlua_print(lstate);
return ERROR_OTHER;
}
@@ -999,7 +1021,7 @@ Object nlua_exec(const String str, const Array args, Error *err)
nlua_push_Object(lstate, args.items[i], false);
}
- if (lua_pcall(lstate, (int)args.size, 1, 0)) {
+ if (nlua_pcall(lstate, (int)args.size, 1)) {
size_t len;
const char *errstr = lua_tolstring(lstate, -1, &len);
api_set_error(err, kErrorTypeException,
@@ -1032,7 +1054,7 @@ Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Erro
nlua_push_Object(lstate, args.items[i], false);
}
- if (lua_pcall(lstate, nargs, retval ? 1 : 0, 0)) {
+ if (nlua_pcall(lstate, nargs, retval ? 1 : 0)) {
// if err is passed, the caller will deal with the error.
if (err) {
size_t len;
@@ -1126,7 +1148,7 @@ void ex_luado(exarg_T *const eap)
if (lcmd_len >= IOSIZE) {
xfree(lcmd);
}
- if (lua_pcall(lstate, 0, 1, 0)) {
+ if (nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5110: Error executing lua: %.*s"));
return;
}
@@ -1138,7 +1160,7 @@ void ex_luado(exarg_T *const eap)
const char *old_line = (const char *)ml_get_buf(curbuf, l, false);
lua_pushstring(lstate, old_line);
lua_pushnumber(lstate, (lua_Number)l);
- if (lua_pcall(lstate, 2, 1, 0)) {
+ if (nlua_pcall(lstate, 2, 1)) {
nlua_error(lstate, _("E5111: Error calling lua: %.*s"));
break;
}
@@ -1189,7 +1211,7 @@ bool nlua_exec_file(const char *path)
return false;
}
- if (lua_pcall(lstate, 0, 0, 0)) {
+ if (nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
return false;
}
@@ -1241,7 +1263,7 @@ int nlua_expand_pat(expand_T *xp, char_u *pat, int *num_results, char_u ***resul
// [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)pat, STRLEN(pat));
- if (lua_pcall(lstate, 1, 2, 0) != 0) {
+ if (nlua_pcall(lstate, 1, 2) != 0) {
nlua_error(lstate,
_("Error executing vim._expand_pat: %.*s"));
return FAIL;
@@ -1394,7 +1416,7 @@ void nlua_execute_on_key(int c)
// [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)buf, buf_len);
- if (lua_pcall(lstate, 1, 0, 0)) {
+ if (nlua_pcall(lstate, 1, 0)) {
nlua_error(lstate,
_("Error executing vim.on_key Lua callback: %.*s"));
}