diff options
Diffstat (limited to 'src/nvim/viml/executor/executor.c')
-rw-r--r-- | src/nvim/viml/executor/executor.c | 159 |
1 files changed, 77 insertions, 82 deletions
diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 6f1e847649..a9d05bcd31 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -36,7 +36,19 @@ typedef struct { lua_pushcfunction(lstate, &function); \ lua_call(lstate, 0, numret); \ } while (0) -/// Call C function which expects four arguments +/// Call C function which expects two arguments +/// +/// @param function Called function +/// @param numret Number of returned arguments +/// @param a… Supplied argument (should be a void* pointer) +#define NLUA_CALL_C_FUNCTION_2(lstate, function, numret, a1, a2) \ + do { \ + lua_pushcfunction(lstate, &function); \ + lua_pushlightuserdata(lstate, a1); \ + lua_pushlightuserdata(lstate, a2); \ + lua_call(lstate, 2, numret); \ + } while (0) +/// Call C function which expects three arguments /// /// @param function Called function /// @param numret Number of returned arguments @@ -64,15 +76,19 @@ typedef struct { lua_call(lstate, 4, numret); \ } while (0) -static void set_lua_error(lua_State *lstate, LuaError *lerr) +/// Convert lua error into a Vim error message +/// +/// @param lstate Lua interpreter state. +/// @param[in] msg Message base, must contain one `%s`. +static void nlua_error(lua_State *const lstate, const char *const msg) FUNC_ATTR_NONNULL_ALL { - const char *const str = lua_tolstring(lstate, -1, &lerr->lua_err_str.size); - lerr->lua_err_str.data = xmemdupz(str, lerr->lua_err_str.size); - lua_pop(lstate, 1); + size_t len; + const char *const str = lua_tolstring(lstate, -1, &len); + + EMSG2(msg, str); - // FIXME? More specific error? - set_api_error("Error while executing lua code", &lerr->err); + lua_pop(lstate, 1); } /// Compare two strings, ignoring case @@ -94,25 +110,26 @@ static int nlua_stricmp(lua_State *lstate) FUNC_ATTR_NONNULL_ALL /// Evaluate lua string /// -/// Expects three values on the stack: string to evaluate, pointer to the -/// location where result is saved, pointer to the location where error is -/// saved. Always returns nothing (from the lua point of view). +/// Expects two values on the stack: string to evaluate, pointer to the +/// location where result is saved. Always returns nothing (from the lua point +/// of view). static int nlua_exec_lua_string(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { - String *str = (String *) lua_touserdata(lstate, 1); - Object *obj = (Object *) lua_touserdata(lstate, 2); - LuaError *lerr = (LuaError *) lua_touserdata(lstate, 3); - lua_pop(lstate, 3); + String *str = (String *)lua_touserdata(lstate, 1); + typval_T *ret_tv = (typval_T *)lua_touserdata(lstate, 2); + lua_pop(lstate, 2); if (luaL_loadbuffer(lstate, str->data, str->size, NLUA_EVAL_NAME)) { - set_lua_error(lstate, lerr); + nlua_error(lstate, _("E5104: Error while creating lua chunk: %s")); return 0; } if (lua_pcall(lstate, 0, 1, 0)) { - set_lua_error(lstate, lerr); + nlua_error(lstate, _("E5105: Error while calling lua chunk: %s")); + return 0; + } + if (!nlua_pop_typval(lstate, ret_tv)) { return 0; } - *obj = nlua_pop_Object(lstate, &lerr->err); return 0; } @@ -124,8 +141,7 @@ static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL lua_pushcfunction(lstate, &nlua_stricmp); lua_setglobal(lstate, "stricmp"); if (luaL_dostring(lstate, (char *) &vim_module[0])) { - LuaError lerr; - set_lua_error(lstate, &lerr); + nlua_error(lstate, _("E5106: Error while creating vim module: %s")); return 1; } nlua_add_api_functions(lstate); @@ -150,14 +166,6 @@ static lua_State *init_lua(void) return lstate; } -static Object exec_lua_string(lua_State *lstate, String str, LuaError *lerr) - FUNC_ATTR_NONNULL_ALL -{ - Object ret = { kObjectTypeNil, { false } }; - NLUA_CALL_C_FUNCTION_3(lstate, nlua_exec_lua_string, 0, &str, &ret, lerr); - return ret; -} - static lua_State *global_lstate = NULL; /// Execute lua string @@ -165,28 +173,17 @@ static lua_State *global_lstate = NULL; /// Used for :lua. /// /// @param[in] str String to execute. -/// @param[out] err Location where error will be saved. -/// @param[out] err_str Location where lua error string will be saved, if any. +/// @param[out] ret_tv Location where result will be saved. /// /// @return Result of the execution. -Object executor_exec_lua(String str, Error *err, String *err_str) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +void executor_exec_lua(String str, typval_T *ret_tv) + FUNC_ATTR_NONNULL_ALL { if (global_lstate == NULL) { global_lstate = init_lua(); } - LuaError lerr = { - .err = { .set = false }, - .lua_err_str = STRING_INIT, - }; - - Object ret = exec_lua_string(global_lstate, str, &lerr); - - *err = lerr.err; - *err_str = lerr.lua_err_str; - - return ret; + NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_lua_string, 0, &str, ret_tv); } /// Evaluate lua string @@ -196,75 +193,73 @@ Object executor_exec_lua(String str, Error *err, String *err_str) /// 1. String to evaluate. /// 2. _A value. /// 3. Pointer to location where result is saved. -/// 4. Pointer to location where error will be saved. /// /// @param[in,out] lstate Lua interpreter state. static int nlua_eval_lua_string(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { - String *str = (String *) lua_touserdata(lstate, 1); - Object *arg = (Object *) lua_touserdata(lstate, 2); - Object *ret = (Object *) lua_touserdata(lstate, 3); - LuaError *lerr = (LuaError *) lua_touserdata(lstate, 4); + String *str = (String *)lua_touserdata(lstate, 1); + typval_T *arg = (typval_T *)lua_touserdata(lstate, 2); + typval_T *ret_tv = (typval_T *)lua_touserdata(lstate, 3); + lua_pop(lstate, 3); garray_T str_ga; ga_init(&str_ga, 1, 80); -#define EVALHEADER "local _A=select(1,...) return " - ga_concat_len(&str_ga, EVALHEADER, sizeof(EVALHEADER) - 1); +#define EVALHEADER "local _A=select(1,...) return (" + const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str->size + 1; + char *lcmd; + if (lcmd_len < IOSIZE) { + lcmd = (char *)IObuff; + } else { + lcmd = xmalloc(lcmd_len); + } + memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1); + memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size); + lcmd[lcmd_len - 1] = ')'; #undef EVALHEADER - ga_concat_len(&str_ga, str->data, str->size); - if (luaL_loadbuffer(lstate, str_ga.ga_data, (size_t) str_ga.ga_len, - NLUA_EVAL_NAME)) { - set_lua_error(lstate, lerr); + if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) { + nlua_error(lstate, + _("E5107: Error while creating lua chunk for luaeval(): %s")); return 0; } - ga_clear(&str_ga); + if (lcmd != (char *)IObuff) { + xfree(lcmd); + } - nlua_push_Object(lstate, *arg); + if (arg == NULL || arg->v_type == VAR_UNKNOWN) { + lua_pushnil(lstate); + } else { + nlua_push_typval(lstate, arg); + } if (lua_pcall(lstate, 1, 1, 0)) { - set_lua_error(lstate, lerr); + nlua_error(lstate, + _("E5108: Error while calling lua chunk for luaeval(): %s")); + return 0; + } + if (!nlua_pop_typval(lstate, ret_tv)) { return 0; } - *ret = nlua_pop_Object(lstate, &lerr->err); return 0; } -static Object eval_lua_string(lua_State *lstate, String str, Object arg, - LuaError *lerr) - FUNC_ATTR_NONNULL_ALL -{ - Object ret = { kObjectTypeNil, { false } }; - NLUA_CALL_C_FUNCTION_4(lstate, nlua_eval_lua_string, 0, - &str, &arg, &ret, lerr); - return ret; -} - /// Evaluate lua string /// /// Used for luaeval(). /// /// @param[in] str String to execute. -/// @param[out] err Location where error will be saved. -/// @param[out] err_str Location where lua error string will be saved, if any. +/// @param[in] arg Second argument to `luaeval()`. +/// @param[out] ret_tv Location where result will be saved. /// /// @return Result of the execution. -Object executor_eval_lua(String str, Object arg, Error *err, String *err_str) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +void executor_eval_lua(const String str, typval_T *const arg, + typval_T *const ret_tv) + FUNC_ATTR_NONNULL_ALL { if (global_lstate == NULL) { global_lstate = init_lua(); } - LuaError lerr = { - .err = { .set = false }, - .lua_err_str = STRING_INIT, - }; - - Object ret = eval_lua_string(global_lstate, str, arg, &lerr); - - *err = lerr.err; - *err_str = lerr.lua_err_str; - - return ret; + NLUA_CALL_C_FUNCTION_3(global_lstate, nlua_eval_lua_string, 0, + (void *)&str, arg, ret_tv); } |