diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-10 16:21:57 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-10 16:21:57 +0200 |
commit | 21e881fd6c085e615c438ceb6eb438712f5c5075 (patch) | |
tree | ca86d5360965f7dd2e81a978d3d8b821905b6710 /src | |
parent | 408f8a5bf7934e7a5aa113fd3a55899db70dd73a (diff) | |
download | lanes-21e881fd6c085e615c438ceb6eb438712f5c5075.tar.gz lanes-21e881fd6c085e615c438ceb6eb438712f5c5075.tar.bz2 lanes-21e881fd6c085e615c438ceb6eb438712f5c5075.zip |
C++ migration: wrap lua type values in an enum class for type safety and debugging purposes
Diffstat (limited to 'src')
-rw-r--r-- | src/compat.h | 27 | ||||
-rw-r--r-- | src/lanes.cpp | 13 | ||||
-rw-r--r-- | src/macros_and_utils.h | 10 | ||||
-rw-r--r-- | src/tools.cpp | 30 |
4 files changed, 57 insertions, 23 deletions
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); | |||
98 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.4, we don't care about the actual value | 98 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.4, we don't care about the actual value |
99 | 99 | ||
100 | #endif // LUA_VERSION_NUM == 504 | 100 | #endif // LUA_VERSION_NUM == 504 |
101 | |||
102 | // ################################################################################################# | ||
103 | |||
104 | // a wrapper over lua types to see them easier in a debugger | ||
105 | enum class LuaType | ||
106 | { | ||
107 | NONE = LUA_TNONE, | ||
108 | NIL = LUA_TNIL, | ||
109 | BOOLEAN = LUA_TBOOLEAN, | ||
110 | LIGHTUSERDATA = LUA_TLIGHTUSERDATA, | ||
111 | NUMBER = LUA_TNUMBER, | ||
112 | STRING = LUA_TSTRING, | ||
113 | TABLE = LUA_TTABLE, | ||
114 | FUNCTION = LUA_TFUNCTION, | ||
115 | USERDATA = LUA_TUSERDATA, | ||
116 | THREAD = LUA_TTHREAD, | ||
117 | CDATA = 10 // LuaJIT CDATA | ||
118 | }; | ||
119 | |||
120 | inline LuaType lua_type_as_enum(lua_State* L, int idx_) | ||
121 | { | ||
122 | return static_cast<LuaType>(lua_type(L, idx_)); | ||
123 | } | ||
124 | inline char const* lua_typename(lua_State* L, LuaType t_) | ||
125 | { | ||
126 | return lua_typename(L, static_cast<int>(t_)); | ||
127 | } | ||
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) | |||
967 | LUAG_FUNC(register) | 967 | LUAG_FUNC(register) |
968 | { | 968 | { |
969 | char const* name = luaL_checkstring(L, 1); | 969 | char const* name = luaL_checkstring(L, 1); |
970 | int const mod_type = lua_type(L, 2); | 970 | LuaType const mod_type{ lua_type_as_enum(L, 2) }; |
971 | // ignore extra parameters, just in case | 971 | // ignore extra parameters, just in case |
972 | lua_settop(L, 2); | 972 | lua_settop(L, 2); |
973 | luaL_argcheck(L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); | 973 | luaL_argcheck(L, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type"); |
974 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); | 974 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); |
975 | STACK_CHECK_START_REL(L, 0); // "name" mod_table | 975 | STACK_CHECK_START_REL(L, 0); // "name" mod_table |
976 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); | 976 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); |
@@ -1226,7 +1226,8 @@ LUAG_FUNC(lane_new) | |||
1226 | STACK_CHECK(L2, 0); | 1226 | STACK_CHECK(L2, 0); |
1227 | 1227 | ||
1228 | // Lane main function | 1228 | // Lane main function |
1229 | if (lua_type(L, 1) == LUA_TFUNCTION) | 1229 | LuaType const func_type{ lua_type_as_enum(L, 1) }; |
1230 | if (func_type == LuaType::FUNCTION) | ||
1230 | { | 1231 | { |
1231 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); | 1232 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); |
1232 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 1233 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); |
@@ -1238,7 +1239,7 @@ LUAG_FUNC(lane_new) | |||
1238 | luaL_error(L, "tried to copy unsupported types"); // doesn't return | 1239 | luaL_error(L, "tried to copy unsupported types"); // doesn't return |
1239 | } | 1240 | } |
1240 | } | 1241 | } |
1241 | else if (lua_type(L, 1) == LUA_TSTRING) | 1242 | else if (func_type == LuaType::STRING) |
1242 | { | 1243 | { |
1243 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END)); | 1244 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END)); |
1244 | // compile the string | 1245 | // compile the string |
@@ -1247,6 +1248,10 @@ LUAG_FUNC(lane_new) | |||
1247 | luaL_error(L, "error when parsing lane function code"); // doesn't return | 1248 | luaL_error(L, "error when parsing lane function code"); // doesn't return |
1248 | } | 1249 | } |
1249 | } | 1250 | } |
1251 | else | ||
1252 | { | ||
1253 | luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); // doesn't return | ||
1254 | } | ||
1250 | STACK_CHECK(L, 0); | 1255 | STACK_CHECK(L, 0); |
1251 | STACK_CHECK(L2, 1); | 1256 | STACK_CHECK(L2, 1); |
1252 | ASSERT_L(lua_isfunction(L2, 1)); | 1257 | 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 = []{}> | |||
182 | struct Unique | 182 | struct Unique |
183 | { | 183 | { |
184 | T m_val; | 184 | T m_val; |
185 | Unique() = default; | 185 | constexpr Unique() = default; |
186 | operator T() const { return m_val; } | 186 | constexpr operator T() const { return m_val; } |
187 | explicit Unique(T b_) : m_val{ b_ } {} | 187 | constexpr explicit Unique(T b_) : m_val{ b_ } {} |
188 | }; | 188 | }; |
189 | 189 | ||
190 | // ################################################################################################# | ||
191 | |||
190 | using Source = Unique<lua_State*>; | 192 | using Source = Unique<lua_State*>; |
191 | using Dest = Unique<lua_State*>; | 193 | 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) | |||
104 | 104 | ||
105 | for( i = 1; i <= top; ++ i) | 105 | for( i = 1; i <= top; ++ i) |
106 | { | 106 | { |
107 | int type = lua_type( L, i); | 107 | LuaType type{ lua_type_as_enum(L, i) }; |
108 | 108 | ||
109 | fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename( L, type)); | 109 | fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename( L, type)); |
110 | 110 | ||
@@ -1851,8 +1851,8 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1851 | [[nodiscard]] bool inter_copy_one(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_) | 1851 | [[nodiscard]] bool inter_copy_one(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_) |
1852 | { | 1852 | { |
1853 | bool ret{ true }; | 1853 | bool ret{ true }; |
1854 | int val_type = lua_type( L, i); | 1854 | LuaType val_type{ lua_type_as_enum(L, i) }; |
1855 | static int const pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); | 1855 | static constexpr int pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); |
1856 | STACK_GROW( L2, 1); | 1856 | STACK_GROW( L2, 1); |
1857 | STACK_CHECK_START_REL(L, 0); // L // L2 | 1857 | STACK_CHECK_START_REL(L, 0); // L // L2 |
1858 | STACK_CHECK_START_REL(L2, 0); // L // L2 | 1858 | STACK_CHECK_START_REL(L2, 0); // L // L2 |
@@ -1862,7 +1862,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1862 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[static_cast<int>(vt_)])); | 1862 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[static_cast<int>(vt_)])); |
1863 | 1863 | ||
1864 | // Non-POD can be skipped if its metatable contains { __lanesignore = true } | 1864 | // Non-POD can be skipped if its metatable contains { __lanesignore = true } |
1865 | if( ((1 << val_type) & pod_mask) == 0) | 1865 | if( ((1 << static_cast<int>(val_type)) & pod_mask) == 0) |
1866 | { | 1866 | { |
1867 | if( lua_getmetatable( L, i)) // ... mt | 1867 | if( lua_getmetatable( L, i)) // ... mt |
1868 | { | 1868 | { |
@@ -1870,7 +1870,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1870 | if( lua_isboolean( L, -1) && lua_toboolean( L, -1)) | 1870 | if( lua_isboolean( L, -1) && lua_toboolean( L, -1)) |
1871 | { | 1871 | { |
1872 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "__lanesignore -> LUA_TNIL\n" INDENT_END)); | 1872 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "__lanesignore -> LUA_TNIL\n" INDENT_END)); |
1873 | val_type = LUA_TNIL; | 1873 | val_type = LuaType::NIL; |
1874 | } | 1874 | } |
1875 | lua_pop( L, 2); // ... | 1875 | lua_pop( L, 2); // ... |
1876 | } | 1876 | } |
@@ -1882,7 +1882,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1882 | { | 1882 | { |
1883 | /* Basic types allowed both as values, and as table keys */ | 1883 | /* Basic types allowed both as values, and as table keys */ |
1884 | 1884 | ||
1885 | case LUA_TBOOLEAN: | 1885 | case LuaType::BOOLEAN: |
1886 | { | 1886 | { |
1887 | int const v{ lua_toboolean(L, i) }; | 1887 | int const v{ lua_toboolean(L, i) }; |
1888 | DEBUGSPEW_CODE( fprintf( stderr, "%s\n", v ? "true" : "false")); | 1888 | DEBUGSPEW_CODE( fprintf( stderr, "%s\n", v ? "true" : "false")); |
@@ -1890,7 +1890,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1890 | } | 1890 | } |
1891 | break; | 1891 | break; |
1892 | 1892 | ||
1893 | case LUA_TNUMBER: | 1893 | case LuaType::NUMBER: |
1894 | /* LNUM patch support (keeping integer accuracy) */ | 1894 | /* LNUM patch support (keeping integer accuracy) */ |
1895 | #if defined LUA_LNUM || LUA_VERSION_NUM >= 503 | 1895 | #if defined LUA_LNUM || LUA_VERSION_NUM >= 503 |
1896 | if( lua_isinteger( L, i)) | 1896 | if( lua_isinteger( L, i)) |
@@ -1909,7 +1909,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1909 | } | 1909 | } |
1910 | break; | 1910 | break; |
1911 | 1911 | ||
1912 | case LUA_TSTRING: | 1912 | case LuaType::STRING: |
1913 | { | 1913 | { |
1914 | size_t len; | 1914 | size_t len; |
1915 | char const* s = lua_tolstring( L, i, &len); | 1915 | char const* s = lua_tolstring( L, i, &len); |
@@ -1918,7 +1918,7 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1918 | } | 1918 | } |
1919 | break; | 1919 | break; |
1920 | 1920 | ||
1921 | case LUA_TLIGHTUSERDATA: | 1921 | case LuaType::LIGHTUSERDATA: |
1922 | { | 1922 | { |
1923 | void* p = lua_touserdata( L, i); | 1923 | void* p = lua_touserdata( L, i); |
1924 | DEBUGSPEW_CODE( fprintf( stderr, "%p\n", p)); | 1924 | DEBUGSPEW_CODE( fprintf( stderr, "%p\n", p)); |
@@ -1928,11 +1928,11 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1928 | 1928 | ||
1929 | /* The following types are not allowed as table keys */ | 1929 | /* The following types are not allowed as table keys */ |
1930 | 1930 | ||
1931 | case LUA_TUSERDATA: | 1931 | case LuaType::USERDATA: |
1932 | ret = inter_copy_userdata(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); | 1932 | ret = inter_copy_userdata(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); |
1933 | break; | 1933 | break; |
1934 | 1934 | ||
1935 | case LUA_TNIL: | 1935 | case LuaType::NIL: |
1936 | if (vt_ == VT::KEY) | 1936 | if (vt_ == VT::KEY) |
1937 | { | 1937 | { |
1938 | ret = false; | 1938 | ret = false; |
@@ -1941,18 +1941,18 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1941 | lua_pushnil( L2); | 1941 | lua_pushnil( L2); |
1942 | break; | 1942 | break; |
1943 | 1943 | ||
1944 | case LUA_TFUNCTION: | 1944 | case LuaType::FUNCTION: |
1945 | ret = inter_copy_function(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); | 1945 | ret = inter_copy_function(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); |
1946 | break; | 1946 | break; |
1947 | 1947 | ||
1948 | case LUA_TTABLE: | 1948 | case LuaType::TABLE: |
1949 | ret = inter_copy_table(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); | 1949 | ret = inter_copy_table(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); |
1950 | break; | 1950 | break; |
1951 | 1951 | ||
1952 | /* The following types cannot be copied */ | 1952 | /* The following types cannot be copied */ |
1953 | 1953 | ||
1954 | case 10: // LuaJIT CDATA | 1954 | case LuaType::CDATA: |
1955 | case LUA_TTHREAD: | 1955 | case LuaType::THREAD: |
1956 | ret = false; | 1956 | ret = false; |
1957 | break; | 1957 | break; |
1958 | } | 1958 | } |