Skip to content

Commit

Permalink
Add prefix to <struct key_def> and Lua code buffer
Browse files Browse the repository at this point in the history
It allows the module be loaded on tarantool versions, which already have
built-in key_def module without name collisions.

In fact, two problems are solved:

1. After symbols unhiding internal key_def_lua buffer with Lua code
   becomes visible and is preferred over module shipped one (on Linux).
2. Modification of cdata metatype is not allowed in LuaJIT, so we should
   use another structure name for Lua (not <struct key_def>). The reason
   is that built-in module is already loadedand already calls its
   ffi.metatype() on <struct key_def>.
  • Loading branch information
Totktonada committed Sep 4, 2020
1 parent bd5489c commit 645c890
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 7 deletions.
5 changes: 4 additions & 1 deletion cmake/utils.cmake
Expand Up @@ -19,8 +19,11 @@ function(lua_source varname filename)
file(MAKE_DIRECTORY ${dstdir})
endif()

# NB: We prepend the array name with the project name to avoid
# possible name collisions (say, with the same named built-in
# tarantool module).
ADD_CUSTOM_COMMAND(OUTPUT ${dstfile}
COMMAND ${ECHO} 'const char ${module}_lua[] =' > ${tmpfile}
COMMAND ${ECHO} 'const char ${PROJECT_NAME}_${module}_lua[] =' > ${tmpfile}
COMMAND ${CMAKE_BINARY_DIR}/extra/txt2c ${srcfile} >> ${tmpfile}
COMMAND ${ECHO} '\;' >> ${tmpfile}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${tmpfile} ${dstfile}
Expand Down
8 changes: 6 additions & 2 deletions key_def/init.c
Expand Up @@ -9,7 +9,11 @@
* initialization code.
*/

extern char key_def_lua[];
/*
* Note: It is prefixed with the project name to don't clash with
* tarantool symbol.
*/
extern char key_def_key_def_lua[];

/**
* Execute key_def.lua when key_def.so is loaded.
Expand All @@ -21,7 +25,7 @@ setup(void)
int top = lua_gettop(L);

const char *modname = "key_def";
const char *modsrc = key_def_lua;
const char *modsrc = key_def_key_def_lua;
const char *modfile = lua_pushfstring(L,
"@key_def/builtin/%s.lua", modname);
if (luaL_loadbuffer(L, modsrc, strlen(modsrc), modfile)) {
Expand Down
12 changes: 10 additions & 2 deletions key_def/key_def.c
Expand Up @@ -495,8 +495,16 @@ lbox_key_def_new(struct lua_State *L)
LUA_API int
luaopen_key_def(struct lua_State *L)
{
luaL_cdef(L, "struct key_def;");
CTID_STRUCT_KEY_DEF_REF = luaL_ctypeid(L, "struct key_def&");
/*
* ffi.metatype() cannot be called twice on the same type.
*
* Tarantool has built-in key_def Lua module since
* 2.2.0-255-g22db9c264, which already calls
* ffi.metatype() on <struct key_def>. We should use
* another name within the external module.
*/
luaL_cdef(L, "struct key_def_key_def;");
CTID_STRUCT_KEY_DEF_REF = luaL_ctypeid(L, "struct key_def_key_def *");

/* Export C functions to Lua. */
static const struct luaL_Reg meta[] = {
Expand Down
4 changes: 2 additions & 2 deletions key_def/key_def.lua
@@ -1,6 +1,6 @@
local ffi = require('ffi')
local key_def = require('key_def')
local key_def_t = ffi.typeof('struct key_def')
local key_def_t = ffi.typeof('struct key_def_key_def')

local methods = {
['extract_key'] = key_def.extract_key,
Expand All @@ -15,5 +15,5 @@ ffi.metatype(key_def_t, {
__index = function(self, key)
return methods[key]
end,
__tostring = function(self) return "<struct key_def &>" end,
__tostring = function(self) return '<struct key_def_key_def *>' end,
})

0 comments on commit 645c890

Please sign in to comment.