aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2018-11-27 17:58:32 +0100
committerBenoit Germain <bnt.germain@gmail.com>2018-11-27 17:58:32 +0100
commit8d097de830d8daf1411cc54ba267f21ecfc3204d (patch)
tree2b5c2ba1268f7f9ecdde09c96dd9c311c2338e58
parent3aed735e5523af04ff24fd73c4b38944d3ab283d (diff)
downloadlanes-8d097de830d8daf1411cc54ba267f21ecfc3204d.tar.gz
lanes-8d097de830d8daf1411cc54ba267f21ecfc3204d.tar.bz2
lanes-8d097de830d8daf1411cc54ba267f21ecfc3204d.zip
Lua 5.4 support
Diffstat (limited to '')
-rw-r--r--CHANGES4
-rw-r--r--deep_test/deep_test.vcxproj72
-rw-r--r--deep_test/deep_test.vcxproj.user6
-rw-r--r--lanes-3.13.0-0.rockspec2
-rw-r--r--src/compat.c33
-rw-r--r--src/compat.h30
-rw-r--r--src/deep.c2
-rw-r--r--src/keeper.c13
-rw-r--r--src/lanes.c11
-rw-r--r--src/tools.c91
-rw-r--r--src/universe.c2
-rw-r--r--tests/protect_allocator.lua2
12 files changed, 233 insertions, 35 deletions
diff --git a/CHANGES b/CHANGES
index 4ad4aa9..d862341 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 143: BGe 27-Nov-18
4 * Lua 5.4 support
5 * __lanesclone and lanes.nameof support userdata uservalue(s)
6
3CHANGE 142: BGe 26-Nov-18 7CHANGE 142: BGe 26-Nov-18
4 * Version is available in public header 8 * Version is available in public header
5 9
diff --git a/deep_test/deep_test.vcxproj b/deep_test/deep_test.vcxproj
index 6137ea7..110a191 100644
--- a/deep_test/deep_test.vcxproj
+++ b/deep_test/deep_test.vcxproj
@@ -5,6 +5,14 @@
5 <Configuration>Debug 5.3</Configuration> 5 <Configuration>Debug 5.3</Configuration>
6 <Platform>Win32</Platform> 6 <Platform>Win32</Platform>
7 </ProjectConfiguration> 7 </ProjectConfiguration>
8 <ProjectConfiguration Include="Debug 5.4|Win32">
9 <Configuration>Debug 5.4</Configuration>
10 <Platform>Win32</Platform>
11 </ProjectConfiguration>
12 <ProjectConfiguration Include="Debug 5.4|x64">
13 <Configuration>Debug 5.4</Configuration>
14 <Platform>x64</Platform>
15 </ProjectConfiguration>
8 <ProjectConfiguration Include="Release 5.3|Win32"> 16 <ProjectConfiguration Include="Release 5.3|Win32">
9 <Configuration>Release 5.3</Configuration> 17 <Configuration>Release 5.3</Configuration>
10 <Platform>Win32</Platform> 18 <Platform>Win32</Platform>
@@ -31,6 +39,12 @@
31 <PlatformToolset>v141</PlatformToolset> 39 <PlatformToolset>v141</PlatformToolset>
32 <CharacterSet>MultiByte</CharacterSet> 40 <CharacterSet>MultiByte</CharacterSet>
33 </PropertyGroup> 41 </PropertyGroup>
42 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'" Label="Configuration">
43 <ConfigurationType>DynamicLibrary</ConfigurationType>
44 <UseDebugLibraries>true</UseDebugLibraries>
45 <PlatformToolset>v141</PlatformToolset>
46 <CharacterSet>MultiByte</CharacterSet>
47 </PropertyGroup>
34 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'" Label="Configuration"> 48 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'" Label="Configuration">
35 <ConfigurationType>Application</ConfigurationType> 49 <ConfigurationType>Application</ConfigurationType>
36 <UseDebugLibraries>false</UseDebugLibraries> 50 <UseDebugLibraries>false</UseDebugLibraries>
@@ -44,6 +58,12 @@
44 <PlatformToolset>v141</PlatformToolset> 58 <PlatformToolset>v141</PlatformToolset>
45 <CharacterSet>MultiByte</CharacterSet> 59 <CharacterSet>MultiByte</CharacterSet>
46 </PropertyGroup> 60 </PropertyGroup>
61 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'" Label="Configuration">
62 <ConfigurationType>DynamicLibrary</ConfigurationType>
63 <UseDebugLibraries>true</UseDebugLibraries>
64 <PlatformToolset>v141</PlatformToolset>
65 <CharacterSet>MultiByte</CharacterSet>
66 </PropertyGroup>
47 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'" Label="Configuration"> 67 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'" Label="Configuration">
48 <ConfigurationType>Application</ConfigurationType> 68 <ConfigurationType>Application</ConfigurationType>
49 <UseDebugLibraries>false</UseDebugLibraries> 69 <UseDebugLibraries>false</UseDebugLibraries>
@@ -59,12 +79,18 @@
59 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'"> 79 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">
60 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 80 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
61 </ImportGroup> 81 </ImportGroup>
82 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'" Label="PropertySheets">
83 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
84 </ImportGroup>
62 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'"> 85 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">
63 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 86 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
64 </ImportGroup> 87 </ImportGroup>
65 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> 88 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">
66 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 89 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
67 </ImportGroup> 90 </ImportGroup>
91 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'" Label="PropertySheets">
92 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
93 </ImportGroup>
68 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'"> 94 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'">
69 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 95 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
70 </ImportGroup> 96 </ImportGroup>
@@ -74,11 +100,21 @@
74 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 100 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir>
75 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 101 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
76 </PropertyGroup> 102 </PropertyGroup>
103 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
104 <TargetExt>.dll</TargetExt>
105 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir>
106 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
107 </PropertyGroup>
77 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'"> 108 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|Win32'">
78 <TargetExt>.dll</TargetExt> 109 <TargetExt>.dll</TargetExt>
79 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir> 110 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir>
80 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir> 111 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
81 </PropertyGroup> 112 </PropertyGroup>
113 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">
114 <TargetExt>.dll</TargetExt>
115 <OutDir>$(SolutionDir)_Output\$(ProjectName)\$(PlatformName)\$(Configuration)\</OutDir>
116 <IntDir>$(SolutionDir)_Tmp\$(ProjectName)\$(PlatformName)\$(Configuration)\</IntDir>
117 </PropertyGroup>
82 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'"> 118 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|x64'">
83 <ClCompile> 119 <ClCompile>
84 <WarningLevel>Level3</WarningLevel> 120 <WarningLevel>Level3</WarningLevel>
@@ -115,6 +151,24 @@
115 <AdditionalLibraryDirectories>$(SolutionDir)..\lualib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> 151 <AdditionalLibraryDirectories>$(SolutionDir)..\lualib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
116 </Link> 152 </Link>
117 </ItemDefinitionGroup> 153 </ItemDefinitionGroup>
154 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|Win32'">
155 <ClCompile>
156 <WarningLevel>Level3</WarningLevel>
157 <Optimization>Disabled</Optimization>
158 <SDLCheck>true</SDLCheck>
159 <ConformanceMode>true</ConformanceMode>
160 <AdditionalIncludeDirectories>$(SolutionDir)Lanes\lanes\src;$(SolutionDir)..\lualib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
161 <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
162 </ClCompile>
163 <PostBuildEvent>
164 <Command>xcopy /R /F /Y /I "$(TargetPath)" $(SolutionDir)..\framework\</Command>
165 <Message>Copy to framework</Message>
166 </PostBuildEvent>
167 <Link>
168 <AdditionalDependencies>lua53.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>
169 <AdditionalLibraryDirectories>$(SolutionDir)..\lualib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
170 </Link>
171 </ItemDefinitionGroup>
118 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'"> 172 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.3|x64'">
119 <ClCompile> 173 <ClCompile>
120 <WarningLevel>Level3</WarningLevel> 174 <WarningLevel>Level3</WarningLevel>
@@ -133,6 +187,24 @@
133 <AdditionalLibraryDirectories>$(SolutionDir)..\lualib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> 187 <AdditionalLibraryDirectories>$(SolutionDir)..\lualib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
134 </Link> 188 </Link>
135 </ItemDefinitionGroup> 189 </ItemDefinitionGroup>
190 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
191 <ClCompile>
192 <WarningLevel>Level3</WarningLevel>
193 <Optimization>Disabled</Optimization>
194 <SDLCheck>true</SDLCheck>
195 <ConformanceMode>true</ConformanceMode>
196 <AdditionalIncludeDirectories>$(SolutionDir)Lanes\lanes\src;$(SolutionDir)..\lualib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
197 <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
198 </ClCompile>
199 <PostBuildEvent>
200 <Command>xcopy /R /F /Y /I "$(TargetPath)" $(SolutionDir)..\framework\</Command>
201 <Message>Copy to framework</Message>
202 </PostBuildEvent>
203 <Link>
204 <AdditionalDependencies>lua53.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>
205 <AdditionalLibraryDirectories>$(SolutionDir)..\lualib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
206 </Link>
207 </ItemDefinitionGroup>
136 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'"> 208 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release 5.3|Win32'">
137 <ClCompile> 209 <ClCompile>
138 <WarningLevel>Level3</WarningLevel> 210 <WarningLevel>Level3</WarningLevel>
diff --git a/deep_test/deep_test.vcxproj.user b/deep_test/deep_test.vcxproj.user
index 745772f..372bf91 100644
--- a/deep_test/deep_test.vcxproj.user
+++ b/deep_test/deep_test.vcxproj.user
@@ -6,4 +6,10 @@
6 <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments> 6 <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments>
7 <LocalDebuggerWorkingDirectory>D:\Boulot\anubis\Lua\bindings\Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> 7 <LocalDebuggerWorkingDirectory>D:\Boulot\anubis\Lua\bindings\Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory>
8 </PropertyGroup> 8 </PropertyGroup>
9 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
10 <LocalDebuggerCommand>D:\Boulot\anubis\Lua\framework\lua53.exe</LocalDebuggerCommand>
11 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
12 <LocalDebuggerCommandArguments>-i deeptest.lua</LocalDebuggerCommandArguments>
13 <LocalDebuggerWorkingDirectory>D:\Boulot\anubis\Lua\bindings\Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory>
14 </PropertyGroup>
9</Project> \ No newline at end of file 15</Project> \ No newline at end of file
diff --git a/lanes-3.13.0-0.rockspec b/lanes-3.13.0-0.rockspec
index fca228a..dec529e 100644
--- a/lanes-3.13.0-0.rockspec
+++ b/lanes-3.13.0-0.rockspec
@@ -36,7 +36,7 @@ supported_platforms= { "win32",
36} 36}
37 37
38dependencies= { 38dependencies= {
39 "lua >= 5.1", -- builds with either 5.1, 5.2 and 5.3 39 "lua >= 5.1", -- builds with either 5.1, 5.2, 5.3 and 5.4
40} 40}
41 41
42build = { 42build = {
diff --git a/src/compat.c b/src/compat.c
index c5e29f5..9f36090 100644
--- a/src/compat.c
+++ b/src/compat.c
@@ -4,6 +4,7 @@
4 * ############################################################################################### 4 * ###############################################################################################
5 */ 5 */
6#include "compat.h" 6#include "compat.h"
7#include "macros_and_utils.h"
7 8
8/* 9/*
9** Copied from Lua 5.2 loadlib.c 10** Copied from Lua 5.2 loadlib.c
@@ -42,3 +43,35 @@ void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int
42} 43}
43#endif // LUA_VERSION_NUM 44#endif // LUA_VERSION_NUM
44 45
46#if LUA_VERSION_NUM < 504
47
48void* lua_newuserdatauv( lua_State* L, size_t sz, int nuvalue)
49{
50 ASSERT_L( nuvalue <= 1);
51 return lua_newuserdata( L, sz);
52}
53
54int lua_getiuservalue( lua_State* L, int idx, int n)
55{
56 if( n > 1)
57 {
58 lua_pushnil( L);
59 return LUA_TNONE;
60 }
61 lua_getuservalue( L, idx);
62 return lua_type( L, -1);
63}
64
65int lua_setiuservalue( lua_State* L, int idx, int n)
66{
67 if( n > 1)
68 {
69 lua_pop( L, 1);
70 return 0;
71 }
72 (void) lua_setuservalue( L, idx);
73 return 1; // I guess anything non-0 is ok
74}
75
76#endif // LUA_VERSION_NUM
77
diff --git a/src/compat.h b/src/compat.h
index 998edef..eaa9f85 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -5,7 +5,8 @@
5#include "lualib.h" 5#include "lualib.h"
6#include "lauxlib.h" 6#include "lauxlib.h"
7 7
8// code is now preferring Lua 5.3 API 8// code is now preferring Lua 5.4 API
9
9// add some Lua 5.3-style API when building for Lua 5.1 10// add some Lua 5.3-style API when building for Lua 5.1
10#if LUA_VERSION_NUM == 501 11#if LUA_VERSION_NUM == 501
11#define lua501_equal lua_equal 12#define lua501_equal lua_equal
@@ -18,7 +19,8 @@
18#define LUA_OK 0 19#define LUA_OK 0
19#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value 20#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value
20void luaL_requiref (lua_State* L, const char* modname, lua_CFunction openf, int glb); // implementation copied from Lua 5.2 sources 21void luaL_requiref (lua_State* L, const char* modname, lua_CFunction openf, int glb); // implementation copied from Lua 5.2 sources
21#define lua503_dump( L, writer, data, strip) lua_dump( L, writer, data) 22#define lua504_dump( L, writer, data, strip) lua_dump( L, writer, data)
23#define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.1
22#endif // LUA_VERSION_NUM == 501 24#endif // LUA_VERSION_NUM == 501
23 25
24// wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way 26// wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way
@@ -30,7 +32,8 @@ void luaL_requiref (lua_State* L, const char* modname, lua_CFunction openf, int
30#define lua_lessthan( L, a, b) lua_compare( L, a, b, LUA_OPLT) 32#define lua_lessthan( L, a, b) lua_compare( L, a, b, LUA_OPLT)
31#endif // lua_lessthan 33#endif // lua_lessthan
32#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0) 34#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0)
33#define lua503_dump( L, writer, data, strip) lua_dump( L, writer, data) 35#define lua504_dump( L, writer, data, strip) lua_dump( L, writer, data)
36#define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.2
34#endif // LUA_VERSION_NUM == 502 37#endif // LUA_VERSION_NUM == 502
35 38
36// wrap Lua 5.3 calls under Lua 5.1 API when it is simpler that way 39// wrap Lua 5.3 calls under Lua 5.1 API when it is simpler that way
@@ -42,8 +45,27 @@ void luaL_requiref (lua_State* L, const char* modname, lua_CFunction openf, int
42#define lua_lessthan( L, a, b) lua_compare( L, a, b, LUA_OPLT) 45#define lua_lessthan( L, a, b) lua_compare( L, a, b, LUA_OPLT)
43#endif // lua_lessthan 46#endif // lua_lessthan
44#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0) 47#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0)
45#define lua503_dump lua_dump 48#define lua504_dump lua_dump
46#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 49#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
47#endif // LUA_VERSION_NUM == 503 50#endif // LUA_VERSION_NUM == 503
48 51
52#if LUA_VERSION_NUM < 504
53void *lua_newuserdatauv( lua_State* L, size_t sz, int nuvalue);
54int lua_getiuservalue( lua_State* L, int idx, int n);
55int lua_setiuservalue( lua_State* L, int idx, int n);
56#endif // LUA_VERSION_NUM < 504
57
58// wrap Lua 5.4 calls under Lua 5.1 API when it is simpler that way
59#if LUA_VERSION_NUM == 504
60#ifndef lua501_equal // already defined when compatibility is active in luaconf.h
61#define lua501_equal( L, a, b) lua_compare( L, a, b, LUA_OPEQ)
62#endif // lua501_equal
63#ifndef lua_lessthan // already defined when compatibility is active in luaconf.h
64#define lua_lessthan( L, a, b) lua_compare( L, a, b, LUA_OPLT)
65#endif // lua_lessthan
66#define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0)
67#define lua504_dump lua_dump
68#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
69#endif // LUA_VERSION_NUM == 504
70
49#endif // __COMPAT_H__ 71#endif // __COMPAT_H__
diff --git a/src/deep.c b/src/deep.c
index fd92e0c..fadb895 100644
--- a/src/deep.c
+++ b/src/deep.c
@@ -283,7 +283,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, Lo
283 STACK_GROW( L, 7); 283 STACK_GROW( L, 7);
284 STACK_CHECK( L, 0); 284 STACK_CHECK( L, 0);
285 285
286 proxy = lua_newuserdata( L, sizeof(DeepPrelude*)); // DPC proxy 286 proxy = lua_newuserdatauv( L, sizeof(DeepPrelude*), 0); // DPC proxy
287 ASSERT_L( proxy); 287 ASSERT_L( proxy);
288 *proxy = prelude; 288 *proxy = prelude;
289 289
diff --git a/src/keeper.c b/src/keeper.c
index 7eda598..05e9a02 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -65,6 +65,8 @@ typedef struct
65 lua_Integer limit; 65 lua_Integer limit;
66} keeper_fifo; 66} keeper_fifo;
67 67
68static int const CONTENTS_TABLE = 1;
69
68// replaces the fifo ud by its uservalue on the stack 70// replaces the fifo ud by its uservalue on the stack
69static keeper_fifo* prepare_fifo_access( lua_State* L, int idx_) 71static keeper_fifo* prepare_fifo_access( lua_State* L, int idx_)
70{ 72{
@@ -74,7 +76,7 @@ static keeper_fifo* prepare_fifo_access( lua_State* L, int idx_)
74 idx_ = lua_absindex( L, idx_); 76 idx_ = lua_absindex( L, idx_);
75 STACK_GROW( L, 1); 77 STACK_GROW( L, 1);
76 // we can replace the fifo userdata in the stack without fear of it being GCed, there are other references around 78 // we can replace the fifo userdata in the stack without fear of it being GCed, there are other references around
77 lua_getuservalue( L, idx_); 79 lua_getiuservalue( L, idx_, CONTENTS_TABLE);
78 lua_replace( L, idx_); 80 lua_replace( L, idx_);
79 } 81 }
80 return fifo; 82 return fifo;
@@ -86,12 +88,13 @@ static void fifo_new( lua_State* L)
86{ 88{
87 keeper_fifo* fifo; 89 keeper_fifo* fifo;
88 STACK_GROW( L, 2); 90 STACK_GROW( L, 2);
89 fifo = (keeper_fifo*) lua_newuserdata( L, sizeof( keeper_fifo)); 91 // a fifo full userdata has one uservalue, the table that holds the actual fifo contents
92 fifo = (keeper_fifo*)lua_newuserdatauv( L, sizeof( keeper_fifo), 1);
90 fifo->first = 1; 93 fifo->first = 1;
91 fifo->count = 0; 94 fifo->count = 0;
92 fifo->limit = -1; 95 fifo->limit = -1;
93 lua_newtable( L); 96 lua_newtable( L);
94 lua_setuservalue( L, -2); 97 lua_setiuservalue( L, -2, CONTENTS_TABLE);
95} 98}
96 99
97// in: expect fifo ... on top of the stack 100// in: expect fifo ... on top of the stack
@@ -422,7 +425,7 @@ int keepercall_set( lua_State* L)
422 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit); 425 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit);
423 lua_remove( L, -2); // fifos fifo 426 lua_remove( L, -2); // fifos fifo
424 lua_newtable( L); // fifos fifo {} 427 lua_newtable( L); // fifos fifo {}
425 lua_setuservalue( L, -2); // fifos fifo 428 lua_setiuservalue( L, -2, CONTENTS_TABLE); // fifos fifo
426 fifo->first = 1; 429 fifo->first = 1;
427 fifo->count = 0; 430 fifo->count = 0;
428 } 431 }
@@ -450,7 +453,7 @@ int keepercall_set( lua_State* L)
450 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit) && (count < fifo->limit); 453 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit) && (count < fifo->limit);
451 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! 454 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
452 lua_newtable( L); // fifos key [val [, ...]] fifo {} 455 lua_newtable( L); // fifos key [val [, ...]] fifo {}
453 lua_setuservalue( L, -2); // fifos key [val [, ...]] fifo 456 lua_setiuservalue( L, -2, CONTENTS_TABLE); // fifos key [val [, ...]] fifo
454 fifo->first = 1; 457 fifo->first = 1;
455 fifo->count = 0; 458 fifo->count = 0;
456 } 459 }
diff --git a/src/lanes.c b/src/lanes.c
index 2ad9bd9..90da9bf 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -114,7 +114,7 @@ static void securize_debug_threadname( lua_State* L, Lane* s)
114{ 114{
115 STACK_CHECK( L, 0); 115 STACK_CHECK( L, 0);
116 STACK_GROW( L, 3); 116 STACK_GROW( L, 3);
117 lua_getuservalue( L, 1); 117 lua_getiuservalue( L, 1, 1);
118 lua_newtable( L); 118 lua_newtable( L);
119 // Lua 5.1 can't do 's->debug_name = lua_pushstring( L, s->debug_name);' 119 // Lua 5.1 can't do 's->debug_name = lua_pushstring( L, s->debug_name);'
120 lua_pushstring( L, s->debug_name); 120 lua_pushstring( L, s->debug_name);
@@ -1376,7 +1376,8 @@ LUAG_FUNC( lane_new)
1376 1376
1377 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1377 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1378 // 1378 //
1379 ud = lua_newuserdata( L, sizeof( Lane*)); // func libs cancelstep priority globals package required gc_cb lane 1379 // a Lane full userdata needs a single uservalue
1380 ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs cancelstep priority globals package required gc_cb lane
1380 s = *ud = (Lane*) malloc( sizeof( Lane)); 1381 s = *ud = (Lane*) malloc( sizeof( Lane));
1381 if( s == NULL) 1382 if( s == NULL)
1382 { 1383 {
@@ -1422,7 +1423,7 @@ LUAG_FUNC( lane_new)
1422 lua_rawset( L, -3); // func libs cancelstep priority globals package required gc_cb lane uv 1423 lua_rawset( L, -3); // func libs cancelstep priority globals package required gc_cb lane uv
1423 } 1424 }
1424 1425
1425 lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane 1426 lua_setiuservalue( L, -2, 1); // func libs cancelstep priority globals package required gc_cb lane
1426 1427
1427 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive). 1428 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive).
1428 REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] 1429 REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...]
@@ -1461,7 +1462,7 @@ LUAG_FUNC( thread_gc)
1461 Lane* s = lua_toLane( L, 1); // ud 1462 Lane* s = lua_toLane( L, 1); // ud
1462 1463
1463 // if there a gc callback? 1464 // if there a gc callback?
1464 lua_getuservalue( L, 1); // ud uservalue 1465 lua_getiuservalue( L, 1, 1); // ud uservalue
1465 push_unique_key( L, GCCB_KEY); // ud uservalue __gc 1466 push_unique_key( L, GCCB_KEY); // ud uservalue __gc
1466 lua_rawget( L, -2); // ud uservalue gc_cb|nil 1467 lua_rawget( L, -2); // ud uservalue gc_cb|nil
1467 if( !lua_isnil( L, -1)) 1468 if( !lua_isnil( L, -1))
@@ -1724,7 +1725,7 @@ LUAG_FUNC( thread_index)
1724 // first, check that we don't already have an environment that holds the requested value 1725 // first, check that we don't already have an environment that holds the requested value
1725 { 1726 {
1726 // If key is found in the uservalue, return it 1727 // If key is found in the uservalue, return it
1727 lua_getuservalue( L, UD); 1728 lua_getiuservalue( L, UD, 1);
1728 lua_pushvalue( L, KEY); 1729 lua_pushvalue( L, KEY);
1729 lua_rawget( L, USR); 1730 lua_rawget( L, USR);
1730 if( !lua_isnil( L, -1)) 1731 if( !lua_isnil( L, -1))
diff --git a/src/tools.c b/src/tools.c
index 8885dea..4a0aec6 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -120,7 +120,7 @@ static void* protected_lua_Alloc( void *ud, void *ptr, size_t osize, size_t nsiz
120static int luaG_provide_protected_allocator( lua_State* L) 120static int luaG_provide_protected_allocator( lua_State* L)
121{ 121{
122 Universe* U = universe_get( L); 122 Universe* U = universe_get( L);
123 AllocatorDefinition* def = lua_newuserdata( L, sizeof(AllocatorDefinition)); 123 AllocatorDefinition* def = lua_newuserdatauv( L, sizeof(AllocatorDefinition), 0);
124 def->allocF = protected_lua_Alloc; 124 def->allocF = protected_lua_Alloc;
125 def->allocUD = &U->protected_allocator; 125 def->allocUD = &U->protected_allocator;
126 return 1; 126 return 1;
@@ -356,7 +356,7 @@ FuncSubType luaG_getfuncsubtype( lua_State *L, int _i)
356 // the provided writer fails with code 666 356 // the provided writer fails with code 666
357 // therefore, anytime we get 666, this means that lua_dump() attempted a dump 357 // therefore, anytime we get 666, this means that lua_dump() attempted a dump
358 // all other cases mean this is either a C or LuaJIT-fast function 358 // all other cases mean this is either a C or LuaJIT-fast function
359 dumpres = lua503_dump( L, dummy_writer, NULL, 0); 359 dumpres = lua504_dump( L, dummy_writer, NULL, 0);
360 lua_pop( L, mustpush); 360 lua_pop( L, mustpush);
361 if( dumpres == 666) 361 if( dumpres == 666)
362 { 362 {
@@ -1223,19 +1223,27 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1223 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U 1223 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1224 } 1224 }
1225 STACK_MID( L, 2); 1225 STACK_MID( L, 2);
1226 // search in the object's uservalue if it is a table 1226 // search in the object's uservalues
1227 lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u}
1228 if( lua_istable( L, -1))
1229 { 1227 {
1230 ++ depth_; 1228 int uvi = 1;
1231 lua_pushliteral( L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" 1229 while( lua_getiuservalue( L, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u}
1232 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} 1230 {
1233 shortest_ = discover_object_name_recur( L, shortest_, depth_); 1231 if( lua_istable( L, -1)) // if it is a table, look inside
1234 lua_pushnil( L); // o "r" {c} {fqn} ... {?} k v {u} nil 1232 {
1235 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} 1233 ++ depth_;
1236 -- depth_; 1234 lua_pushliteral( L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue"
1235 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u}
1236 shortest_ = discover_object_name_recur( L, shortest_, depth_);
1237 lua_pushnil( L); // o "r" {c} {fqn} ... {?} k v {u} nil
1238 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u}
1239 -- depth_;
1240 }
1241 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1242 ++ uvi;
1243 }
1244 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
1245 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1237 } 1246 }
1238 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1239 STACK_MID( L, 2); 1247 STACK_MID( L, 2);
1240 break; 1248 break;
1241 } 1249 }
@@ -1436,7 +1444,7 @@ static void inter_copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_
1436 // "value returned is the error code returned by the last call 1444 // "value returned is the error code returned by the last call
1437 // to the writer" (and we only return 0) 1445 // to the writer" (and we only return 0)
1438 // not sure this could ever fail but for memory shortage reasons 1446 // not sure this could ever fail but for memory shortage reasons
1439 if( lua503_dump( L, buf_writer, &b, 0) != 0) 1447 if( lua504_dump( L, buf_writer, &b, 0) != 0)
1440 { 1448 {
1441 luaL_error( L, "internal error: function dump failed."); 1449 luaL_error( L, "internal error: function dump failed.");
1442 } 1450 }
@@ -1846,7 +1854,32 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1846 STACK_MID( L, 3); 1854 STACK_MID( L, 3);
1847 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size 1855 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size
1848 lua_pop( L, 1); // ... mt __lanesclone 1856 lua_pop( L, 1); // ... mt __lanesclone
1849 clone = lua_newuserdata( L2, userdata_size); // ... u 1857 // we need to copy over the uservalues of the userdata as well
1858 lua_pushnil( L2); // ... nil
1859 {
1860 int const clone_i = lua_gettop( L2);
1861 int uvi = 0;
1862 while( lua_getiuservalue( L, i, uvi + 1) != LUA_TNONE) // ... mt __lanesclone uv
1863 {
1864 luaG_inter_move( U, L, L2, 1, mode_); // ... mt __lanesclone // ... nil [uv]+
1865 ++ uvi;
1866 }
1867 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
1868 lua_pop( L, 1); // ... mt __lanesclone
1869 // create the clone userdata with the required number of uservalue slots
1870 clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... nil [uv]+ u
1871 lua_replace( L2, clone_i); // ... u [uv]+
1872 // assign uservalues
1873 while( uvi > 0)
1874 {
1875 // this pops the value from the stack
1876 lua_setiuservalue( L2, clone_i, uvi); // ... u [uv]+
1877 -- uvi;
1878 }
1879 // when we are done, all uservalues are popped from the stack
1880 STACK_MID( L2, 1); // ... u
1881 }
1882 STACK_MID( L, 2); // ... mt __lanesclone
1850 // call cloning function in source state to perform the actual memory cloning 1883 // call cloning function in source state to perform the actual memory cloning
1851 lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone 1884 lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone
1852 lua_pushlightuserdata( L, source); // ... mt __lanesclone source 1885 lua_pushlightuserdata( L, source); // ... mt __lanesclone source
@@ -1920,13 +1953,37 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1920 source = lua_touserdata( L, -1); 1953 source = lua_touserdata( L, -1);
1921 lookup_table( L2, L, i, mode_, upName_); // ... u // ... mt 1954 lookup_table( L2, L, i, mode_, upName_); // ... u // ... mt
1922 // __lanesclone should always exist because we woudln't be restoring data from a userdata_clone_sentinel closure to begin with 1955 // __lanesclone should always exist because we woudln't be restoring data from a userdata_clone_sentinel closure to begin with
1923 lua_getfield( L2, -1, "__lanesclone"); // // ... mt __lanesclone 1956 lua_getfield( L2, -1, "__lanesclone"); // ... mt __lanesclone
1924 lua_pushvalue( L2, -1); // ... mt __lanesclone __lanesclone 1957 lua_pushvalue( L2, -1); // ... mt __lanesclone __lanesclone
1925 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone 1958 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone
1926 lua_call( L2, 0, 1); // ... mt __lanesclone size 1959 lua_call( L2, 0, 1); // ... mt __lanesclone size
1927 userdata_size = (size_t) lua_tointeger( L2, -1); // ... mt __lanesclone size 1960 userdata_size = (size_t) lua_tointeger( L2, -1); // ... mt __lanesclone size
1928 lua_pop( L2, 1); // ... mt __lanesclone 1961 lua_pop( L2, 1); // ... mt __lanesclone
1929 clone = lua_newuserdata( L2, userdata_size); // ... mt __lanesclone u 1962 lua_pushnil( L2); // ... mt __lanesclone nil
1963 {
1964 int const clone_i = lua_gettop( L2);
1965 int uvi = 0;
1966 while( lua_getiuservalue( L, i, uvi + 1) != LUA_TNONE) // ... u uv
1967 {
1968 luaG_inter_move( U, L, L2, 1, mode_); // ... u // ... mt __lanesclone nil [uv]+
1969 ++ uvi;
1970 }
1971 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
1972 lua_pop( L, 1); // ... u
1973 // create the clone userdata with the required number of uservalue slots
1974 clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... mt __lanesclone nil [uv]+ u
1975 lua_replace( L2, clone_i); // ... mt __lanesclone u [uv]+
1976 // assign uservalues
1977 while( uvi > 0)
1978 {
1979 // this pops the value from the stack
1980 lua_setiuservalue( L2, clone_i, uvi); // ... mt __lanesclone u [uv]+
1981 -- uvi;
1982 }
1983 // when we are done, all uservalues are popped from the stack
1984 STACK_MID( L2, 3); // ... mt __lanesclone u
1985 }
1986 STACK_MID( L, 1); // u
1930 lua_insert( L2, -3); // ... u mt __lanesclone 1987 lua_insert( L2, -3); // ... u mt __lanesclone
1931 lua_pushlightuserdata( L2, clone); // ... u mt __lanesclone clone 1988 lua_pushlightuserdata( L2, clone); // ... u mt __lanesclone clone
1932 lua_pushlightuserdata( L2, source); // ... u mt __lanesclone clone source 1989 lua_pushlightuserdata( L2, source); // ... u mt __lanesclone clone source
diff --git a/src/universe.c b/src/universe.c
index d531bf2..e1cd38f 100644
--- a/src/universe.c
+++ b/src/universe.c
@@ -43,7 +43,7 @@ static DECLARE_CONST_UNIQUE_KEY( UNIVERSE_REGKEY, 0x9f877b2cf078f17f);
43 43
44Universe* universe_create( lua_State* L) 44Universe* universe_create( lua_State* L)
45{ 45{
46 Universe* U = (Universe*) lua_newuserdata( L, sizeof(Universe)); // universe 46 Universe* U = (Universe*) lua_newuserdatauv( L, sizeof(Universe), 0); // universe
47 memset( U, 0, sizeof( Universe)); 47 memset( U, 0, sizeof( Universe));
48 STACK_CHECK( L, 1); 48 STACK_CHECK( L, 1);
49 REGISTRY_SET( L, UNIVERSE_REGKEY, lua_pushvalue(L, -2)); // universe 49 REGISTRY_SET( L, UNIVERSE_REGKEY, lua_pushvalue(L, -2)); // universe
diff --git a/tests/protect_allocator.lua b/tests/protect_allocator.lua
index 8877eaf..593261e 100644
--- a/tests/protect_allocator.lua
+++ b/tests/protect_allocator.lua
@@ -1,6 +1,6 @@
1local print = print 1local print = print
2 2
3local lanes = require "lanes".configure{ with_timers = false, protect_allocator=true} 3local lanes = require "lanes".configure{ with_timers = false, allocator="protected"}
4 4
5local linda = lanes.linda() 5local linda = lanes.linda()
6 6