Skip to content

Commit

Permalink
feat(lua): add proper support of luv threads
Browse files Browse the repository at this point in the history
  • Loading branch information
erw7 authored and bfredl committed Feb 26, 2022
1 parent d0f8f76 commit b87867e
Show file tree
Hide file tree
Showing 13 changed files with 992 additions and 196 deletions.
48 changes: 48 additions & 0 deletions runtime/lua/vim/_load_package.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-- prevents luacheck from making lints for setting things on vim
local vim = assert(vim)

local pathtrails = {}
vim._so_trails = {}
for s in (package.cpath..';'):gmatch('[^;]*;') do
s = s:sub(1, -2) -- Strip trailing semicolon
-- Find out path patterns. pathtrail should contain something like
-- /?.so, \?.dll. This allows not to bother determining what correct
-- suffixes are.
local pathtrail = s:match('[/\\][^/\\]*%?.*$')
if pathtrail and not pathtrails[pathtrail] then
pathtrails[pathtrail] = true
table.insert(vim._so_trails, pathtrail)
end
end

function vim._load_package(name)
local basename = name:gsub('%.', '/')
local paths = {"lua/"..basename..".lua", "lua/"..basename.."/init.lua"}
local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true})
if #found > 0 then
local f, err = loadfile(found[1])
return f or error(err)
end

local so_paths = {}
for _,trail in ipairs(vim._so_trails) do
local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
table.insert(so_paths, path)
end

found = vim.api.nvim__get_runtime(so_paths, false, {is_lua=true})
if #found > 0 then
-- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
-- a) strip prefix up to and including the first dash, if any
-- b) replace all dots by underscores
-- c) prepend "luaopen_"
-- So "foo-bar.baz" should result in "luaopen_bar_baz"
local dash = name:find("-", 1, true)
local modname = dash and name:sub(dash + 1) or name
local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
return f or error(err)
end
return nil
end

table.insert(package.loaders, 1, vim._load_package)
20 changes: 14 additions & 6 deletions src/cjson/lua_cjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg,

if (has_metatable) {

nlua_pushref(l, nlua_empty_dict_ref);
nlua_pushref(l, nlua_get_empty_dict_ref(l));
if (lua_rawequal(l, -2, -1)) {
as_empty_dict = true;
} else {
Expand Down Expand Up @@ -822,7 +822,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
}
break;
case LUA_TUSERDATA:
nlua_pushref(l, nlua_nil_ref);
nlua_pushref(l, nlua_get_nil_ref(l));
bool is_nil = lua_rawequal(l, -2, -1);
lua_pop(l, 1);
if (is_nil) {
Expand Down Expand Up @@ -1285,7 +1285,7 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json)

/* Handle empty objects */
if (token.type == T_OBJ_END) {
nlua_pushref(l, nlua_empty_dict_ref); \
nlua_pushref(l, nlua_get_empty_dict_ref(l)); \
lua_setmetatable(l, -2); \
json_decode_ascend(json);
return;
Expand Down Expand Up @@ -1392,7 +1392,7 @@ static void json_process_value(lua_State *l, json_parse_t *json,
if (use_luanil) {
lua_pushnil(l);
} else {
nlua_pushref(l, nlua_nil_ref);
nlua_pushref(l, nlua_get_nil_ref(l));
}
break;;
default:
Expand Down Expand Up @@ -1549,7 +1549,15 @@ int lua_cjson_new(lua_State *l)
};

/* Initialise number conversions */
fpconv_init();
lua_getfield(l, LUA_REGISTRYINDEX, "nvim.thread");
bool is_thread = lua_toboolean(l, -1);
lua_pop(l, 1);

// Since fpconv_init does not need to be called multiple times and is not
// thread safe, it should only be called in the main thread.
if (!is_thread) {
fpconv_init();
}

/* Test if array metatables are in registry */
lua_pushlightuserdata(l, json_lightudata_mask(&json_empty_array));
Expand Down Expand Up @@ -1582,7 +1590,7 @@ int lua_cjson_new(lua_State *l)
compat_luaL_setfuncs(l, reg, 1);

/* Set cjson.null */
nlua_pushref(l, nlua_nil_ref);
nlua_pushref(l, nlua_get_nil_ref(l));
lua_setfield(l, -2, "null");

/* Set cjson.empty_array_mt */
Expand Down
3 changes: 3 additions & 0 deletions src/nvim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(LUA_INSPECT_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/inspect.lua)
set(LUA_F_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/F.lua)
set(LUA_META_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_meta.lua)
set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lua)
set(LUA_LOAD_PACKAGE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_load_package.lua)
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json)
set(LINT_SUPPRESS_URL_BASE "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint")
Expand Down Expand Up @@ -336,6 +337,7 @@ add_custom_command(
${LUA_F_MODULE_SOURCE} lua_F_module
${LUA_META_MODULE_SOURCE} lua_meta_module
${LUA_FILETYPE_MODULE_SOURCE} lua_filetype_module
${LUA_LOAD_PACKAGE_MODULE_SOURCE} lua_load_package_module
DEPENDS
${CHAR_BLOB_GENERATOR}
${LUA_VIM_MODULE_SOURCE}
Expand All @@ -344,6 +346,7 @@ add_custom_command(
${LUA_F_MODULE_SOURCE}
${LUA_META_MODULE_SOURCE}
${LUA_FILETYPE_MODULE_SOURCE}
${LUA_LOAD_PACKAGE_MODULE_SOURCE}
VERBATIM
)

Expand Down
2 changes: 1 addition & 1 deletion src/nvim/api/vim.c
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,7 @@ Dictionary nvim__stats(void)
Dictionary rv = ARRAY_DICT_INIT;
PUT(rv, "fsync", INTEGER_OBJ(g_stats.fsync));
PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_refcount));
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
return rv;
}

Expand Down
14 changes: 7 additions & 7 deletions src/nvim/lua/converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate)
&& ret.string_keys_num == 0)) {
ret.type = kObjectTypeArray;
if (tsize == 0 && lua_getmetatable(lstate, -1)) {
nlua_pushref(lstate, nlua_empty_dict_ref);
nlua_pushref(lstate, nlua_get_empty_dict_ref(lstate));
if (lua_rawequal(lstate, -2, -1)) {
ret.type = kObjectTypeDictionary;
}
Expand Down Expand Up @@ -401,7 +401,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
}
case LUA_TUSERDATA: {
// TODO(bfredl): check mt.__call and convert to function?
nlua_pushref(lstate, nlua_nil_ref);
nlua_pushref(lstate, nlua_get_nil_ref(lstate));
bool is_nil = lua_rawequal(lstate, -2, -1);
lua_pop(lstate, 1);
if (is_nil) {
Expand Down Expand Up @@ -445,7 +445,7 @@ static bool typval_conv_special = false;
if (typval_conv_special) { \
lua_pushnil(lstate); \
} else { \
nlua_pushref(lstate, nlua_nil_ref); \
nlua_pushref(lstate, nlua_get_nil_ref(lstate)); \
} \
} while (0)

Expand Down Expand Up @@ -495,7 +495,7 @@ static bool typval_conv_special = false;
nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary); \
} else { \
lua_createtable(lstate, 0, 0); \
nlua_pushref(lstate, nlua_empty_dict_ref); \
nlua_pushref(lstate, nlua_get_empty_dict_ref(lstate)); \
lua_setmetatable(lstate, -2); \
} \
} while (0)
Expand Down Expand Up @@ -734,7 +734,7 @@ void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict, bool special
} else {
lua_createtable(lstate, 0, (int)dict.size);
if (dict.size == 0 && !special) {
nlua_pushref(lstate, nlua_empty_dict_ref);
nlua_pushref(lstate, nlua_get_empty_dict_ref(lstate));
lua_setmetatable(lstate, -2);
}
}
Expand Down Expand Up @@ -782,7 +782,7 @@ void nlua_push_Object(lua_State *lstate, const Object obj, bool special)
if (special) {
lua_pushnil(lstate);
} else {
nlua_pushref(lstate, nlua_nil_ref);
nlua_pushref(lstate, nlua_get_nil_ref(lstate));
}
break;
case kObjectTypeLuaRef: {
Expand Down Expand Up @@ -1206,7 +1206,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
break;

case LUA_TUSERDATA: {
nlua_pushref(lstate, nlua_nil_ref);
nlua_pushref(lstate, nlua_get_nil_ref(lstate));
bool is_nil = lua_rawequal(lstate, -2, -1);
lua_pop(lstate, 1);
if (is_nil) {
Expand Down
Loading

0 comments on commit b87867e

Please sign in to comment.