mirror of
https://github.com/neovim/neovim.git
synced 2026-05-23 21:30:11 +00:00
fix(api): fail fast if has_lua_imp retval looks wrong #39866
This commit is contained in:
@@ -708,6 +708,9 @@ output:write('\n')
|
||||
--- @type {binding: string, api:string}[]
|
||||
local lua_c_functions = {}
|
||||
|
||||
--- Functions which use kRetMultiStack.
|
||||
local lua_retstack = { nvim_buf_call = true, nvim_win_call = true }
|
||||
|
||||
--- Generates C code to bridge RPC API <=> Lua.
|
||||
---
|
||||
--- Inspect the result here:
|
||||
@@ -844,6 +847,9 @@ local function process_function(fn)
|
||||
end
|
||||
|
||||
write_shifted_output(' ENTER_LUA_ACTIVE_STATE(lstate);\n')
|
||||
if fn.has_lua_imp and not lua_retstack[fn.name] then
|
||||
write_shifted_output(' const int pretop = lua_gettop(lstate); (void)pretop;\n')
|
||||
end
|
||||
local free_at_exit_code = ''
|
||||
for i = 1, #free_code do
|
||||
local rev_i = #free_code - i + 1
|
||||
@@ -882,8 +888,14 @@ exit_0:
|
||||
local ret_type = real_type(fn.return_type)
|
||||
local ret_mode = (ret_type == 'Object') and '&' or ''
|
||||
if fn.has_lua_imp then
|
||||
-- it is up to the function to push return values
|
||||
write_shifted_output(' (void)ret;')
|
||||
-- Most has_lua_imp functions are expected to produce a single retval (e.g.
|
||||
-- nvim_buf_get_lines, but not kRetMultiStack callers such as nvim_buf_call). #39851
|
||||
if not lua_retstack[fn.name] then
|
||||
write_shifted_output(
|
||||
' assert((ERROR_SET(&err) || lua_gettop(lstate) == pretop + 1) && "has_lua_imp function must push exactly one return value");\n'
|
||||
)
|
||||
end
|
||||
write_shifted_output(' (void)ret;\n')
|
||||
elseif ret_type:match('^KeyDict_') then
|
||||
write_shifted_output(' nlua_push_keydict(lstate, &ret, %s_table);\n', return_type:sub(9))
|
||||
else
|
||||
|
||||
@@ -1808,6 +1808,9 @@ static int mode_ret(LuaRetMode mode)
|
||||
Object nlua_call_ref_ctx(bool fast, LuaRef ref, const char *name, Array args, LuaRetMode mode,
|
||||
Arena *arena, Error *err)
|
||||
{
|
||||
// Use active_lstate (set by ENTER_LUA_ACTIVE_STATE in gen_api_dispatch.lua) so callbacks run on
|
||||
// the caller's Lua thread. This matters for coroutines: with global_lstate, return values pushed
|
||||
// by kRetMultiStack would land on the main thread's stack, instead of coroutine stack.
|
||||
lua_State *const lstate = active_lstate;
|
||||
int top = lua_gettop(lstate);
|
||||
nlua_pushref(lstate, ref);
|
||||
|
||||
Reference in New Issue
Block a user