diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-06 11:57:49 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-06 11:57:49 +0200 |
| commit | 38a9cded72d663f48eb3154ed2eb495bbf3f80f3 (patch) | |
| tree | cde7cdd94b3795ef6d66fbee416f8c4f8deee192 | |
| parent | 75a7e10527f1588efa00677ee1f8f77591af0921 (diff) | |
| download | lanes-38a9cded72d663f48eb3154ed2eb495bbf3f80f3.tar.gz lanes-38a9cded72d663f48eb3154ed2eb495bbf3f80f3.tar.bz2 lanes-38a9cded72d663f48eb3154ed2eb495bbf3f80f3.zip | |
Fix deep_test for all flavors of Lua
| -rw-r--r-- | deep_test/deep_test.cpp | 135 | ||||
| -rw-r--r-- | deep_test/deep_test.vcxproj | 2 | ||||
| -rw-r--r-- | deep_test/deep_test.vcxproj.user | 13 | ||||
| -rw-r--r-- | deep_test/deeptest.lua | 19 | ||||
| -rw-r--r-- | src/compat.h | 64 |
5 files changed, 152 insertions, 81 deletions
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp index 0a09921..da467f3 100644 --- a/deep_test/deep_test.cpp +++ b/deep_test/deep_test.cpp | |||
| @@ -1,18 +1,12 @@ | |||
| 1 | #include "lanes/src/deep.h" | 1 | #include "lanes/src/deep.h" |
| 2 | #include "lanes/src/compat.h" | 2 | #include "lanes/src/compat.h" |
| 3 | 3 | ||
| 4 | #include <malloc.h> | ||
| 5 | #include <memory.h> | ||
| 6 | #include <assert.h> | ||
| 7 | |||
| 8 | class MyDeepFactory : public DeepFactory | 4 | class MyDeepFactory : public DeepFactory |
| 9 | { | 5 | { |
| 10 | public: | 6 | public: |
| 11 | |||
| 12 | static MyDeepFactory Instance; | 7 | static MyDeepFactory Instance; |
| 13 | 8 | ||
| 14 | private: | 9 | private: |
| 15 | |||
| 16 | void createMetatable(lua_State* const L_) const override | 10 | void createMetatable(lua_State* const L_) const override |
| 17 | { | 11 | { |
| 18 | luaL_getmetatable(L_, "deep"); | 12 | luaL_getmetatable(L_, "deep"); |
| @@ -28,6 +22,7 @@ class MyDeepFactory : public DeepFactory | |||
| 28 | // a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code. | 22 | // a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code. |
| 29 | struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude | 23 | struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude |
| 30 | { | 24 | { |
| 25 | std::atomic<int> inUse{}; | ||
| 31 | lua_Integer val{ 0 }; | 26 | lua_Integer val{ 0 }; |
| 32 | }; | 27 | }; |
| 33 | 28 | ||
| @@ -49,22 +44,20 @@ void MyDeepFactory::deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* c | |||
| 49 | 44 | ||
| 50 | // ################################################################################################# | 45 | // ################################################################################################# |
| 51 | 46 | ||
| 52 | [[nodiscard]] static int deep_set(lua_State* const L_) | 47 | [[nodiscard]] static int deep_gc(lua_State* L) |
| 53 | { | 48 | { |
| 54 | MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L_, 1)) }; | 49 | MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; |
| 55 | lua_Integer i = lua_tointeger(L_, 2); | ||
| 56 | _self->val = i; | ||
| 57 | return 0; | 50 | return 0; |
| 58 | } | 51 | } |
| 59 | 52 | ||
| 60 | // ################################################################################################# | 53 | // ################################################################################################# |
| 61 | 54 | ||
| 62 | [[nodiscard]] static int deep_setuv(lua_State* L) | 55 | [[nodiscard]] static int deep_tostring(lua_State* L) |
| 63 | { | 56 | { |
| 64 | MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; | 57 | MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; |
| 65 | int uv = (int) luaL_optinteger(L, 2, 1); | 58 | _self->inUse.fetch_add(1, std::memory_order_seq_cst); |
| 66 | lua_settop( L, 3); | 59 | lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), _self->val); |
| 67 | lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0); | 60 | _self->inUse.fetch_sub(1, std::memory_order_seq_cst); |
| 68 | return 1; | 61 | return 1; |
| 69 | } | 62 | } |
| 70 | 63 | ||
| @@ -73,44 +66,53 @@ void MyDeepFactory::deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* c | |||
| 73 | // won't actually do anything as deep userdata don't have uservalue slots | 66 | // won't actually do anything as deep userdata don't have uservalue slots |
| 74 | [[nodiscard]] static int deep_getuv(lua_State* L) | 67 | [[nodiscard]] static int deep_getuv(lua_State* L) |
| 75 | { | 68 | { |
| 76 | MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; | 69 | MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; |
| 77 | int uv = (int) luaL_optinteger(L, 2, 1); | 70 | _self->inUse.fetch_add(1, std::memory_order_seq_cst); |
| 78 | lua_getiuservalue( L, 1, uv); | 71 | int _uv = (int) luaL_optinteger(L, 2, 1); |
| 72 | lua_getiuservalue(L, 1, _uv); | ||
| 73 | _self->inUse.fetch_sub(1, std::memory_order_seq_cst); | ||
| 79 | return 1; | 74 | return 1; |
| 80 | } | 75 | } |
| 81 | 76 | ||
| 82 | // ################################################################################################# | 77 | // ################################################################################################# |
| 83 | 78 | ||
| 84 | [[nodiscard]] static int deep_tostring(lua_State* L) | 79 | [[nodiscard]] static int deep_set(lua_State* const L_) |
| 85 | { | 80 | { |
| 86 | MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; | 81 | MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L_, 1)) }; |
| 87 | lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), self->val); | 82 | _self->inUse.fetch_add(1, std::memory_order_seq_cst); |
| 88 | return 1; | 83 | lua_Integer _i = lua_tointeger(L_, 2); |
| 84 | _self->val = _i; | ||
| 85 | _self->inUse.fetch_sub(1, std::memory_order_seq_cst); | ||
| 86 | return 0; | ||
| 89 | } | 87 | } |
| 90 | 88 | ||
| 91 | // ################################################################################################# | 89 | // ################################################################################################# |
| 92 | 90 | ||
| 93 | [[nodiscard]] static int deep_gc(lua_State* L) | 91 | [[nodiscard]] static int deep_setuv(lua_State* L) |
| 94 | { | 92 | { |
| 95 | MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; | 93 | MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; |
| 96 | return 0; | 94 | _self->inUse.fetch_add(1, std::memory_order_seq_cst); |
| 95 | int _uv = (int) luaL_optinteger(L, 2, 1); | ||
| 96 | lua_settop(L, 3); | ||
| 97 | lua_pushboolean(L, lua_setiuservalue(L, 1, _uv) != 0); | ||
| 98 | _self->inUse.fetch_sub(1, std::memory_order_seq_cst); | ||
| 99 | return 1; | ||
| 97 | } | 100 | } |
| 98 | 101 | ||
| 99 | // ################################################################################################# | 102 | // ################################################################################################# |
| 100 | 103 | ||
| 101 | static luaL_Reg const deep_mt[] = | 104 | static luaL_Reg const deep_mt[] = { |
| 102 | { | 105 | { "__gc", deep_gc }, |
| 103 | { "__tostring", deep_tostring}, | 106 | { "__tostring", deep_tostring }, |
| 104 | { "__gc", deep_gc}, | 107 | { "getuv", deep_getuv }, |
| 105 | { "set", deep_set}, | 108 | { "set", deep_set }, |
| 106 | { "setuv", deep_setuv}, | 109 | { "setuv", deep_setuv }, |
| 107 | { "getuv", deep_getuv}, | ||
| 108 | { nullptr, nullptr } | 110 | { nullptr, nullptr } |
| 109 | }; | 111 | }; |
| 110 | 112 | ||
| 111 | // ################################################################################################# | 113 | // ################################################################################################# |
| 112 | 114 | ||
| 113 | int luaD_new_deep( lua_State* L) | 115 | int luaD_new_deep(lua_State* L) |
| 114 | { | 116 | { |
| 115 | int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) }; | 117 | int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) }; |
| 116 | lua_settop(L, 0); | 118 | lua_settop(L, 0); |
| @@ -141,8 +143,8 @@ struct MyClonableUserdata | |||
| 141 | { | 143 | { |
| 142 | MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); | 144 | MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); |
| 143 | int uv = (int) luaL_optinteger(L, 2, 1); | 145 | int uv = (int) luaL_optinteger(L, 2, 1); |
| 144 | lua_settop( L, 3); | 146 | lua_settop(L, 3); |
| 145 | lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0); | 147 | lua_pushboolean(L, lua_setiuservalue(L, 1, uv) != 0); |
| 146 | return 1; | 148 | return 1; |
| 147 | } | 149 | } |
| 148 | 150 | ||
| @@ -152,7 +154,7 @@ struct MyClonableUserdata | |||
| 152 | { | 154 | { |
| 153 | MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); | 155 | MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); |
| 154 | int uv = (int) luaL_optinteger(L, 2, 1); | 156 | int uv = (int) luaL_optinteger(L, 2, 1); |
| 155 | lua_getiuservalue( L, 1, uv); | 157 | lua_getiuservalue(L, 1, uv); |
| 156 | return 1; | 158 | return 1; |
| 157 | } | 159 | } |
| 158 | 160 | ||
| @@ -178,19 +180,18 @@ struct MyClonableUserdata | |||
| 178 | // this is all we need to make a userdata lanes-clonable. no dependency on Lanes code. | 180 | // this is all we need to make a userdata lanes-clonable. no dependency on Lanes code. |
| 179 | [[nodiscard]] static int clonable_lanesclone(lua_State* L) | 181 | [[nodiscard]] static int clonable_lanesclone(lua_State* L) |
| 180 | { | 182 | { |
| 181 | switch( lua_gettop(L)) | 183 | switch (lua_gettop(L)) { |
| 182 | { | 184 | case 3: |
| 183 | case 3: | ||
| 184 | { | 185 | { |
| 185 | MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); | 186 | MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); |
| 186 | MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2)); | 187 | MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2)); |
| 187 | size_t len = lua_tointeger(L, 3); | 188 | size_t len = lua_tointeger(L, 3); |
| 188 | assert( len == sizeof(MyClonableUserdata)); | 189 | assert(len == sizeof(MyClonableUserdata)); |
| 189 | *self = *from; | 190 | *self = *from; |
| 190 | } | 191 | } |
| 191 | return 0; | 192 | return 0; |
| 192 | 193 | ||
| 193 | default: | 194 | default: |
| 194 | raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters"); | 195 | raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters"); |
| 195 | } | 196 | } |
| 196 | return 0; | 197 | return 0; |
| @@ -198,34 +199,32 @@ struct MyClonableUserdata | |||
| 198 | 199 | ||
| 199 | // ################################################################################################# | 200 | // ################################################################################################# |
| 200 | 201 | ||
| 201 | static luaL_Reg const clonable_mt[] = | 202 | static luaL_Reg const clonable_mt[] = { |
| 202 | { | 203 | { "__tostring", clonable_tostring }, |
| 203 | { "__tostring", clonable_tostring}, | 204 | { "__gc", clonable_gc }, |
| 204 | { "__gc", clonable_gc}, | 205 | { "__lanesclone", clonable_lanesclone }, |
| 205 | { "__lanesclone", clonable_lanesclone}, | 206 | { "set", clonable_set }, |
| 206 | { "set", clonable_set}, | 207 | { "setuv", clonable_setuv }, |
| 207 | { "setuv", clonable_setuv}, | 208 | { "getuv", clonable_getuv }, |
| 208 | { "getuv", clonable_getuv}, | ||
| 209 | { nullptr, nullptr } | 209 | { nullptr, nullptr } |
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | // ################################################################################################# | 212 | // ################################################################################################# |
| 213 | 213 | ||
| 214 | int luaD_new_clonable( lua_State* L) | 214 | int luaD_new_clonable(lua_State* L) |
| 215 | { | 215 | { |
| 216 | int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) }; | 216 | int const _nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) }; |
| 217 | lua_newuserdatauv( L, sizeof(MyClonableUserdata), nuv); | 217 | lua_newuserdatauv(L, sizeof(MyClonableUserdata), _nuv); |
| 218 | luaL_setmetatable( L, "clonable"); | 218 | luaG_setmetatable(L, "clonable"); |
| 219 | return 1; | 219 | return 1; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | // ################################################################################################# | 222 | // ################################################################################################# |
| 223 | // ################################################################################################# | 223 | // ################################################################################################# |
| 224 | 224 | ||
| 225 | static luaL_Reg const deep_module[] = | 225 | static luaL_Reg const deep_module[] = { |
| 226 | { | 226 | { "new_deep", luaD_new_deep }, |
| 227 | { "new_deep", luaD_new_deep}, | 227 | { "new_clonable", luaD_new_clonable }, |
| 228 | { "new_clonable", luaD_new_clonable}, | ||
| 229 | { nullptr, nullptr } | 228 | { nullptr, nullptr } |
| 230 | }; | 229 | }; |
| 231 | 230 | ||
| @@ -233,24 +232,24 @@ static luaL_Reg const deep_module[] = | |||
| 233 | 232 | ||
| 234 | LANES_API int luaopen_deep_test(lua_State* L) | 233 | LANES_API int luaopen_deep_test(lua_State* L) |
| 235 | { | 234 | { |
| 236 | luaL_newlib( L, deep_module); // M | 235 | luaG_newlib<std::size(deep_module)>(L, deep_module); // M |
| 237 | 236 | ||
| 238 | // preregister the metatables for the types we can instantiate so that Lanes can know about them | 237 | // preregister the metatables for the types we can instantiate so that Lanes can know about them |
| 239 | if (luaL_newmetatable( L, "clonable")) // M mt | 238 | if (luaL_newmetatable(L, "clonable")) // M mt |
| 240 | { | 239 | { |
| 241 | luaL_setfuncs( L, clonable_mt, 0); | 240 | luaG_registerlibfuncs(L, clonable_mt); |
| 242 | lua_pushvalue(L, -1); // M mt mt | 241 | lua_pushvalue(L, -1); // M mt mt |
| 243 | lua_setfield(L, -2, "__index"); // M mt | 242 | lua_setfield(L, -2, "__index"); // M mt |
| 244 | } | 243 | } |
| 245 | lua_setfield(L, -2, "__clonableMT"); // M | 244 | lua_setfield(L, -2, "__clonableMT"); // M |
| 246 | 245 | ||
| 247 | if (luaL_newmetatable( L, "deep")) // mt | 246 | if (luaL_newmetatable(L, "deep")) // mt |
| 248 | { | 247 | { |
| 249 | luaL_setfuncs( L, deep_mt, 0); | 248 | luaG_registerlibfuncs(L, deep_mt); |
| 250 | lua_pushvalue(L, -1); // mt mt | 249 | lua_pushvalue(L, -1); // mt mt |
| 251 | lua_setfield(L, -2, "__index"); // mt | 250 | lua_setfield(L, -2, "__index"); // mt |
| 252 | } | 251 | } |
| 253 | lua_setfield(L, -2, "__deepMT"); // M | 252 | lua_setfield(L, -2, "__deepMT"); // M |
| 254 | 253 | ||
| 255 | return 1; | 254 | return 1; |
| 256 | } | 255 | } |
diff --git a/deep_test/deep_test.vcxproj b/deep_test/deep_test.vcxproj index 43b7ce0..298594e 100644 --- a/deep_test/deep_test.vcxproj +++ b/deep_test/deep_test.vcxproj | |||
| @@ -556,7 +556,7 @@ | |||
| 556 | </ClCompile> | 556 | </ClCompile> |
| 557 | <PostBuildEvent> | 557 | <PostBuildEvent> |
| 558 | <Command>xcopy /R /F /Y /I "$(TargetPath)" $(SolutionDir)..\Lua51\bin\$(Platform)\Debug\</Command> | 558 | <Command>xcopy /R /F /Y /I "$(TargetPath)" $(SolutionDir)..\Lua51\bin\$(Platform)\Debug\</Command> |
| 559 | <Message>Copy to Lua 5.2</Message> | 559 | <Message>Copy to Lua 5.1</Message> |
| 560 | </PostBuildEvent> | 560 | </PostBuildEvent> |
| 561 | <Link> | 561 | <Link> |
| 562 | <AdditionalDependencies>lua51.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | 562 | <AdditionalDependencies>lua51.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
diff --git a/deep_test/deep_test.vcxproj.user b/deep_test/deep_test.vcxproj.user index 24e3d31..257d4e9 100644 --- a/deep_test/deep_test.vcxproj.user +++ b/deep_test/deep_test.vcxproj.user | |||
| @@ -3,20 +3,23 @@ | |||
| 3 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> | 3 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> |
| 4 | <LocalDebuggerCommand>$(SolutionDir)..\Lua53\bin\$(Platform)\Debug\lua53.exe</LocalDebuggerCommand> | 4 | <LocalDebuggerCommand>$(SolutionDir)..\Lua53\bin\$(Platform)\Debug\lua53.exe</LocalDebuggerCommand> |
| 5 | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | 5 | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| 6 | <LocalDebuggerCommandArguments>-i</LocalDebuggerCommandArguments> | 6 | <LocalDebuggerCommandArguments>deeptest.lua</LocalDebuggerCommandArguments> |
| 7 | <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> | 7 | <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> |
| 8 | <RemoteDebuggerCommandArguments>deeptest.lua</RemoteDebuggerCommandArguments> | ||
| 8 | </PropertyGroup> | 9 | </PropertyGroup> |
| 9 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'"> | 10 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.1|x64'"> |
| 10 | <LocalDebuggerCommand>$(SolutionDir)..\Lua52\bin\$(Platform)\Debug\lua51.exe</LocalDebuggerCommand> | 11 | <LocalDebuggerCommand>$(SolutionDir)..\Lua51\bin\$(Platform)\Debug\lua51.exe</LocalDebuggerCommand> |
| 11 | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | 12 | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| 12 | <LocalDebuggerCommandArguments>-i</LocalDebuggerCommandArguments> | 13 | <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments> |
| 13 | <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> | 14 | <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> |
| 15 | <RemoteDebuggerCommandArguments>-i deeptest.lua</RemoteDebuggerCommandArguments> | ||
| 14 | </PropertyGroup> | 16 | </PropertyGroup> |
| 15 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'"> | 17 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.2|x64'"> |
| 16 | <LocalDebuggerCommand>$(SolutionDir)..\Lua51\bin\$(Platform)\Debug\lua52.exe</LocalDebuggerCommand> | 18 | <LocalDebuggerCommand>$(SolutionDir)..\Lua52\bin\$(Platform)\Debug\lua52.exe</LocalDebuggerCommand> |
| 17 | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | 19 | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| 18 | <LocalDebuggerCommandArguments>-i</LocalDebuggerCommandArguments> | 20 | <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments> |
| 19 | <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> | 21 | <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> |
| 22 | <RemoteDebuggerCommandArguments>-i deeptest.lua</RemoteDebuggerCommandArguments> | ||
| 20 | </PropertyGroup> | 23 | </PropertyGroup> |
| 21 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LuaJIT 2.1.0-beta3|x64'"> | 24 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LuaJIT 2.1.0-beta3|x64'"> |
| 22 | <LocalDebuggerCommand>$(SolutionDir)..\LuaJIT-2.1.0-beta3\bin\$(Platform)\luajit210.exe</LocalDebuggerCommand> | 25 | <LocalDebuggerCommand>$(SolutionDir)..\LuaJIT-2.1.0-beta3\bin\$(Platform)\luajit210.exe</LocalDebuggerCommand> |
diff --git a/deep_test/deeptest.lua b/deep_test/deeptest.lua index 09b638c..89e6f0d 100644 --- a/deep_test/deeptest.lua +++ b/deep_test/deeptest.lua | |||
| @@ -6,16 +6,21 @@ local dt = lanes.require "deep_test" | |||
| 6 | 6 | ||
| 7 | local test_deep = true | 7 | local test_deep = true |
| 8 | local test_clonable = true | 8 | local test_clonable = true |
| 9 | local test_uvtype = "string" | 9 | -- lua 5.1->5.2 support a single table uservalue |
| 10 | -- lua 5.3->5.4 supports an arbitrary type uservalue | ||
| 11 | local test_uvtype = (_VERSION == "Lua 5.4") and "function" or (_VERSION == "Lua 5.3") and "string" or "table" | ||
| 12 | -- lua 5.4 supports multiple uservalues | ||
| 10 | local nupvals = _VERSION == "Lua 5.4" and 3 or 1 | 13 | local nupvals = _VERSION == "Lua 5.4" and 3 or 1 |
| 11 | 14 | ||
| 12 | local makeUserValue = function( obj_) | 15 | local makeUserValue = function( obj_) |
| 13 | if test_uvtype == "string" then | 16 | if test_uvtype == "table" then |
| 17 | return {"some uservalue"} | ||
| 18 | elseif test_uvtype == "string" then | ||
| 14 | return "some uservalue" | 19 | return "some uservalue" |
| 15 | elseif test_uvtype == "function" then | 20 | elseif test_uvtype == "function" then |
| 16 | -- a function that pull the userdata as upvalue | 21 | -- a function that pull the userdata as upvalue |
| 17 | local f = function() | 22 | local f = function() |
| 18 | return tostring( obj_) | 23 | return "-> '" .. tostring( obj_) .. "'" |
| 19 | end | 24 | end |
| 20 | return f | 25 | return f |
| 21 | end | 26 | end |
| @@ -25,7 +30,7 @@ local printDeep = function( prefix_, obj_, t_) | |||
| 25 | print( prefix_, obj_) | 30 | print( prefix_, obj_) |
| 26 | for uvi = 1, nupvals do | 31 | for uvi = 1, nupvals do |
| 27 | local uservalue = obj_:getuv(uvi) | 32 | local uservalue = obj_:getuv(uvi) |
| 28 | print ( "uv #" .. uvi, uservalue, type( uservalue) == "function" and uservalue() or "") | 33 | print ("uv #" .. uvi, type( uservalue), uservalue, type(uservalue) == "function" and uservalue() or "") |
| 29 | end | 34 | end |
| 30 | if t_ then | 35 | if t_ then |
| 31 | for k, v in pairs( t_) do | 36 | for k, v in pairs( t_) do |
| @@ -38,10 +43,7 @@ end | |||
| 38 | local performTest = function( obj_) | 43 | local performTest = function( obj_) |
| 39 | -- setup the userdata with some value and a uservalue | 44 | -- setup the userdata with some value and a uservalue |
| 40 | obj_:set( 666) | 45 | obj_:set( 666) |
| 41 | -- lua 5.1->5.2 support a single table uservalue | ||
| 42 | -- lua 5.3 supports an arbitrary type uservalue | ||
| 43 | obj_:setuv( 1, makeUserValue( obj_)) | 46 | obj_:setuv( 1, makeUserValue( obj_)) |
| 44 | -- lua 5.4 supports multiple uservalues of arbitrary types | ||
| 45 | if nupvals > 1 then | 47 | if nupvals > 1 then |
| 46 | -- keep uv #2 as nil | 48 | -- keep uv #2 as nil |
| 47 | obj_:setuv( 3, "ENDUV") | 49 | obj_:setuv( 3, "ENDUV") |
| @@ -95,3 +97,6 @@ if test_clonable then | |||
| 95 | print "CLONABLE" | 97 | print "CLONABLE" |
| 96 | performTest( dt.new_clonable(nupvals)) | 98 | performTest( dt.new_clonable(nupvals)) |
| 97 | end | 99 | end |
| 100 | |||
| 101 | print "================================================================" | ||
| 102 | print "TEST OK" \ No newline at end of file | ||
diff --git a/src/compat.h b/src/compat.h index 1789a8b..58af985 100644 --- a/src/compat.h +++ b/src/compat.h | |||
| @@ -172,10 +172,22 @@ struct Wrap | |||
| 172 | return ::lua_dump(L_, writer_, data_, strip_); | 172 | return ::lua_dump(L_, writer_, data_, strip_); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | template <size_t N> | ||
| 176 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | ||
| 177 | { | ||
| 178 | lua_createtable(L_, 0, N - 1); | ||
| 179 | ::luaL_setfuncs(L_, funcs_, 0); | ||
| 180 | } | ||
| 181 | |||
| 175 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int nup_) | 182 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int nup_) |
| 176 | { | 183 | { |
| 177 | ::luaL_setfuncs(L_, funcs_, nup_); | 184 | ::luaL_setfuncs(L_, funcs_, nup_); |
| 178 | } | 185 | } |
| 186 | |||
| 187 | static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) | ||
| 188 | { | ||
| 189 | ::luaL_setmetatable(L_, tname_.data()); | ||
| 190 | } | ||
| 179 | }; | 191 | }; |
| 180 | 192 | ||
| 181 | // ################################################################################################# | 193 | // ################################################################################################# |
| @@ -188,10 +200,22 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 503>::type> | |||
| 188 | return ::lua_dump(L_, writer_, data_, strip_); | 200 | return ::lua_dump(L_, writer_, data_, strip_); |
| 189 | } | 201 | } |
| 190 | 202 | ||
| 203 | template <size_t N> | ||
| 204 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | ||
| 205 | { | ||
| 206 | lua_createtable(L_, 0, N - 1); | ||
| 207 | ::luaL_setfuncs(L_, funcs_, 0); | ||
| 208 | } | ||
| 209 | |||
| 191 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) | 210 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) |
| 192 | { | 211 | { |
| 193 | ::luaL_setfuncs(L_, funcs_, nup_); | 212 | ::luaL_setfuncs(L_, funcs_, nup_); |
| 194 | } | 213 | } |
| 214 | |||
| 215 | static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) | ||
| 216 | { | ||
| 217 | ::luaL_setmetatable(L_, tname_.data()); | ||
| 218 | } | ||
| 195 | }; | 219 | }; |
| 196 | 220 | ||
| 197 | // ################################################################################################# | 221 | // ################################################################################################# |
| @@ -204,10 +228,22 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 502>::type> | |||
| 204 | return ::lua_dump(L_, writer_, data_); | 228 | return ::lua_dump(L_, writer_, data_); |
| 205 | } | 229 | } |
| 206 | 230 | ||
| 231 | template <size_t N> | ||
| 232 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | ||
| 233 | { | ||
| 234 | lua_createtable(L_, 0, N - 1); | ||
| 235 | ::luaL_setfuncs(L_, funcs_, 0); | ||
| 236 | } | ||
| 237 | |||
| 207 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) | 238 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], int const nup_) |
| 208 | { | 239 | { |
| 209 | ::luaL_setfuncs(L_, funcs_, nup_); | 240 | ::luaL_setfuncs(L_, funcs_, nup_); |
| 210 | } | 241 | } |
| 242 | |||
| 243 | static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) | ||
| 244 | { | ||
| 245 | ::luaL_setmetatable(L_, tname_.data()); | ||
| 246 | } | ||
| 211 | }; | 247 | }; |
| 212 | 248 | ||
| 213 | // ################################################################################################# | 249 | // ################################################################################################# |
| @@ -220,10 +256,23 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 501>::type> | |||
| 220 | return ::lua_dump(L_, writer_, data_); | 256 | return ::lua_dump(L_, writer_, data_); |
| 221 | } | 257 | } |
| 222 | 258 | ||
| 259 | template<size_t N> | ||
| 260 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | ||
| 261 | { | ||
| 262 | lua_createtable(L_, 0, N - 1); | ||
| 263 | ::luaL_register(L_, nullptr, funcs_); | ||
| 264 | } | ||
| 265 | |||
| 223 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], [[maybe_unused]] int const nup_) | 266 | static void luaL_setfuncs(lua_State* const L_, luaL_Reg const funcs_[], [[maybe_unused]] int const nup_) |
| 224 | { | 267 | { |
| 225 | ::luaL_register(L_, nullptr, funcs_); | 268 | ::luaL_register(L_, nullptr, funcs_); |
| 226 | } | 269 | } |
| 270 | |||
| 271 | static void luaL_setmetatable(lua_State* const L_, std::string_view const& tname_) | ||
| 272 | { | ||
| 273 | luaL_getmetatable(L_, tname_.data()); | ||
| 274 | lua_setmetatable(L_, -2); | ||
| 275 | } | ||
| 227 | }; | 276 | }; |
| 228 | 277 | ||
| 229 | // ################################################################################################# | 278 | // ################################################################################################# |
| @@ -248,11 +297,26 @@ LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); | |||
| 248 | 297 | ||
| 249 | // ------------------------------------------------------------------------------------------------- | 298 | // ------------------------------------------------------------------------------------------------- |
| 250 | 299 | ||
| 300 | template<size_t N> | ||
| 301 | inline void luaG_newlib(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | ||
| 302 | { | ||
| 303 | (Wrap<LUA_VERSION_NUM>::luaL_newlib)(L_, funcs_); | ||
| 304 | } | ||
| 305 | |||
| 306 | // ------------------------------------------------------------------------------------------------- | ||
| 307 | |||
| 251 | inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) | 308 | inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) |
| 252 | { | 309 | { |
| 253 | Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0); | 310 | Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0); |
| 254 | } | 311 | } |
| 255 | 312 | ||
| 313 | // ------------------------------------------------------------------------------------------------- | ||
| 314 | |||
| 315 | inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_) | ||
| 316 | { | ||
| 317 | return Wrap<LUA_VERSION_NUM>::luaL_setmetatable(L_, tname_); | ||
| 318 | } | ||
| 319 | |||
| 256 | // ################################################################################################# | 320 | // ################################################################################################# |
| 257 | 321 | ||
| 258 | // must keep as a macro as long as we do constant string concatenations | 322 | // must keep as a macro as long as we do constant string concatenations |
