From 21e881fd6c085e615c438ceb6eb438712f5c5075 Mon Sep 17 00:00:00 2001 From: Benoit Germain <benoit.germain@ubisoft.com> Date: Wed, 10 Apr 2024 16:21:57 +0200 Subject: C++ migration: wrap lua type values in an enum class for type safety and debugging purposes --- src/compat.h | 27 +++++++++++++++++++++++++++ src/lanes.cpp | 13 +++++++++---- src/macros_and_utils.h | 10 ++++++---- src/tools.cpp | 30 +++++++++++++++--------------- 4 files changed, 57 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/compat.h b/src/compat.h index 8ef1b6c..8d10e78 100644 --- a/src/compat.h +++ b/src/compat.h @@ -98,3 +98,30 @@ int lua_setiuservalue( lua_State* L, int idx, int n); #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.4, we don't care about the actual value #endif // LUA_VERSION_NUM == 504 + +// ################################################################################################# + +// a wrapper over lua types to see them easier in a debugger +enum class LuaType +{ + NONE = LUA_TNONE, + NIL = LUA_TNIL, + BOOLEAN = LUA_TBOOLEAN, + LIGHTUSERDATA = LUA_TLIGHTUSERDATA, + NUMBER = LUA_TNUMBER, + STRING = LUA_TSTRING, + TABLE = LUA_TTABLE, + FUNCTION = LUA_TFUNCTION, + USERDATA = LUA_TUSERDATA, + THREAD = LUA_TTHREAD, + CDATA = 10 // LuaJIT CDATA +}; + +inline LuaType lua_type_as_enum(lua_State* L, int idx_) +{ + return static_cast<LuaType>(lua_type(L, idx_)); +} +inline char const* lua_typename(lua_State* L, LuaType t_) +{ + return lua_typename(L, static_cast<int>(t_)); +} diff --git a/src/lanes.cpp b/src/lanes.cpp index 462de0f..1f795cc 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -967,10 +967,10 @@ LUAG_FUNC(require) LUAG_FUNC(register) { char const* name = luaL_checkstring(L, 1); - int const mod_type = lua_type(L, 2); + LuaType const mod_type{ lua_type_as_enum(L, 2) }; // ignore extra parameters, just in case lua_settop(L, 2); - luaL_argcheck(L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); + luaL_argcheck(L, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type"); DEBUGSPEW_CODE(Universe* U = universe_get(L)); STACK_CHECK_START_REL(L, 0); // "name" mod_table DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); @@ -1226,7 +1226,8 @@ LUAG_FUNC(lane_new) STACK_CHECK(L2, 0); // Lane main function - if (lua_type(L, 1) == LUA_TFUNCTION) + LuaType const func_type{ lua_type_as_enum(L, 1) }; + if (func_type == LuaType::FUNCTION) { DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); @@ -1238,7 +1239,7 @@ LUAG_FUNC(lane_new) luaL_error(L, "tried to copy unsupported types"); // doesn't return } } - else if (lua_type(L, 1) == LUA_TSTRING) + else if (func_type == LuaType::STRING) { DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END)); // compile the string @@ -1247,6 +1248,10 @@ LUAG_FUNC(lane_new) luaL_error(L, "error when parsing lane function code"); // doesn't return } } + else + { + luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); // doesn't return + } STACK_CHECK(L, 0); STACK_CHECK(L2, 1); ASSERT_L(lua_isfunction(L2, 1)); diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 99e49f9..e8d5ab5 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -182,10 +182,12 @@ template <typename T, auto = []{}> struct Unique { T m_val; - Unique() = default; - operator T() const { return m_val; } - explicit Unique(T b_) : m_val{ b_ } {} + constexpr Unique() = default; + constexpr operator T() const { return m_val; } + constexpr explicit Unique(T b_) : m_val{ b_ } {} }; +// ################################################################################################# + using Source = Unique<lua_State*>; -using Dest = Unique<lua_State*>; +using Dest = Unique<lua_State*>; \ No newline at end of file diff --git a/src/tools.cpp b/src/tools.cpp index aa95f04..4a6f2a2 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -104,7 +104,7 @@ void luaG_dump( lua_State* L) for( i = 1; i <= top; ++ i) { - int type = lua_type( L, i); + LuaType type{ lua_type_as_enum(L, i) }; fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename( L, type)); @@ -1851,8 +1851,8 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; [[nodiscard]] bool inter_copy_one(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_) { bool ret{ true }; - int val_type = lua_type( L, i); - static int const pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); + LuaType val_type{ lua_type_as_enum(L, i) }; + static constexpr int pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); STACK_GROW( L2, 1); STACK_CHECK_START_REL(L, 0); // L // L2 STACK_CHECK_START_REL(L2, 0); // L // L2 @@ -1862,7 +1862,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[static_cast<int>(vt_)])); // Non-POD can be skipped if its metatable contains { __lanesignore = true } - if( ((1 << val_type) & pod_mask) == 0) + if( ((1 << static_cast<int>(val_type)) & pod_mask) == 0) { if( lua_getmetatable( L, i)) // ... mt { @@ -1870,7 +1870,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; if( lua_isboolean( L, -1) && lua_toboolean( L, -1)) { DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "__lanesignore -> LUA_TNIL\n" INDENT_END)); - val_type = LUA_TNIL; + val_type = LuaType::NIL; } lua_pop( L, 2); // ... } @@ -1882,7 +1882,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; { /* Basic types allowed both as values, and as table keys */ - case LUA_TBOOLEAN: + case LuaType::BOOLEAN: { int const v{ lua_toboolean(L, i) }; DEBUGSPEW_CODE( fprintf( stderr, "%s\n", v ? "true" : "false")); @@ -1890,7 +1890,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; } break; - case LUA_TNUMBER: + case LuaType::NUMBER: /* LNUM patch support (keeping integer accuracy) */ #if defined LUA_LNUM || LUA_VERSION_NUM >= 503 if( lua_isinteger( L, i)) @@ -1909,7 +1909,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; } break; - case LUA_TSTRING: + case LuaType::STRING: { size_t len; char const* s = lua_tolstring( L, i, &len); @@ -1918,7 +1918,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; } break; - case LUA_TLIGHTUSERDATA: + case LuaType::LIGHTUSERDATA: { void* p = lua_touserdata( L, i); DEBUGSPEW_CODE( fprintf( stderr, "%p\n", p)); @@ -1928,11 +1928,11 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; /* The following types are not allowed as table keys */ - case LUA_TUSERDATA: + case LuaType::USERDATA: ret = inter_copy_userdata(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); break; - case LUA_TNIL: + case LuaType::NIL: if (vt_ == VT::KEY) { ret = false; @@ -1941,18 +1941,18 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; lua_pushnil( L2); break; - case LUA_TFUNCTION: + case LuaType::FUNCTION: ret = inter_copy_function(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); break; - case LUA_TTABLE: + case LuaType::TABLE: ret = inter_copy_table(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); break; /* The following types cannot be copied */ - case 10: // LuaJIT CDATA - case LUA_TTHREAD: + case LuaType::CDATA: + case LuaType::THREAD: ret = false; break; } -- cgit v1.2.3-55-g6feb