aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deep_test/deep_test.args.json8
-rw-r--r--deep_test/deep_test.vcxproj.user4
-rw-r--r--src/compat.cpp28
-rw-r--r--src/compat.h4
-rw-r--r--src/intercopycontext.cpp36
5 files changed, 47 insertions, 33 deletions
diff --git a/deep_test/deep_test.args.json b/deep_test/deep_test.args.json
index fbef41c..a1654a6 100644
--- a/deep_test/deep_test.args.json
+++ b/deep_test/deep_test.args.json
@@ -7,6 +7,14 @@
7 "Command": "DeepTest", 7 "Command": "DeepTest",
8 "Items": [ 8 "Items": [
9 { 9 {
10 "Id": "d762af99-3873-4084-a9a1-ae42f57802a0",
11 "Command": "deeptest.lua"
12 },
13 {
14 "Id": "a8d142a9-be5f-459d-8b80-61c7f3a263a1",
15 "Command": "-e \"REPEAT=1000, SIZE=1000\" -i deeptest.lua"
16 },
17 {
10 "Id": "10e30bb2-dc23-4882-b918-b5939c14e588", 18 "Id": "10e30bb2-dc23-4882-b918-b5939c14e588",
11 "Command": "-e \"REPEAT=1000, SIZE=1000 DEEP='stack_abuser'\" -i deeptest.lua" 19 "Command": "-e \"REPEAT=1000, SIZE=1000 DEEP='stack_abuser'\" -i deeptest.lua"
12 } 20 }
diff --git a/deep_test/deep_test.vcxproj.user b/deep_test/deep_test.vcxproj.user
index ed75184..257d4e9 100644
--- a/deep_test/deep_test.vcxproj.user
+++ b/deep_test/deep_test.vcxproj.user
@@ -36,9 +36,9 @@
36 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'"> 36 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 5.4|x64'">
37 <LocalDebuggerCommand>$(SolutionDir)..\framework\lua54.exe</LocalDebuggerCommand> 37 <LocalDebuggerCommand>$(SolutionDir)..\framework\lua54.exe</LocalDebuggerCommand>
38 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> 38 <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
39 <LocalDebuggerCommandArguments>-e "REPEAT=1000, SIZE=1000" -i deeptest.lua</LocalDebuggerCommandArguments> 39 <LocalDebuggerCommandArguments>deeptest.lua</LocalDebuggerCommandArguments>
40 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory> 40 <LocalDebuggerWorkingDirectory>$(SolutionDir)Lanes\lanes\deep_test\</LocalDebuggerWorkingDirectory>
41 <RemoteDebuggerCommandArguments>-e "REPEAT=1000, SIZE=1000" -i deeptest.lua</RemoteDebuggerCommandArguments> 41 <RemoteDebuggerCommandArguments>deeptest.lua</RemoteDebuggerCommandArguments>
42 </PropertyGroup> 42 </PropertyGroup>
43 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug MoonJIT|x64'"> 43 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug MoonJIT|x64'">
44 <LocalDebuggerCommand>$(SolutionDir)..\MoonJIT\bin\$(Platform)\moonjit.exe</LocalDebuggerCommand> 44 <LocalDebuggerCommand>$(SolutionDir)..\MoonJIT\bin\$(Platform)\moonjit.exe</LocalDebuggerCommand>
diff --git a/src/compat.cpp b/src/compat.cpp
index f0a3685..e1e7488 100644
--- a/src/compat.cpp
+++ b/src/compat.cpp
@@ -3,25 +3,37 @@
3 3
4#include "macros_and_utils.h" 4#include "macros_and_utils.h"
5 5
6
7// #################################################################################################
8// ###################################### Lua 5.1 / 5.2 / 5.3 ######################################
9// ################################################################################################# 6// #################################################################################################
10 7
8int luaG_getalluservalues(lua_State* const L_, int const idx_)
9{
10 STACK_CHECK_START_REL(L_, 0);
11 int const _idx{ luaG_absindex(L_, idx_) };
12 int _nuv{ 0 };
13 do {
14 // we don't know how many uservalues we are going to extract, there might be a lot...
15 STACK_GROW(L_, 1);
16 } while (lua_getiuservalue(L_, _idx, ++_nuv) != LUA_TNONE); // L_: ... [uv]* nil
17 // last call returned TNONE and pushed nil, that we don't need
18 lua_pop(L_, 1); // L_: ... [uv]*
19 --_nuv;
20 STACK_CHECK(L_, _nuv);
21 return _nuv;
22}
11 23
12// ################################################################################################# 24// #################################################################################################
13 25
14// a small helper to obtain a module's table from the registry instead of relying on the presence of _G["<name>"] 26// a small helper to obtain a module's table from the registry instead of relying on the presence of _G["<name>"]
15LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_) 27LuaType luaG_getmodule(lua_State* const L_, std::string_view const& name_)
16{ 28{
17 STACK_CHECK_START_REL(L_, 0); 29 STACK_CHECK_START_REL(L_, 0);
18 LuaType _type{ luaG_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) }; // L_: _R._LOADED|nil 30 LuaType _type{ luaG_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) }; // L_: _R._LOADED|nil
19 if (_type != LuaType::TABLE) { // L_: _R._LOADED|nil 31 if (_type != LuaType::TABLE) { // L_: _R._LOADED|nil
20 STACK_CHECK(L_, 1); 32 STACK_CHECK(L_, 1);
21 return _type; 33 return _type;
22 } 34 }
23 _type = luaG_getfield(L_, -1, name_); // L_: _R._LOADED {module}|nil 35 _type = luaG_getfield(L_, -1, name_); // L_: _R._LOADED {module}|nil
24 lua_remove(L_, -2); // L_: {module}|nil 36 lua_remove(L_, -2); // L_: {module}|nil
25 STACK_CHECK(L_, 1); 37 STACK_CHECK(L_, 1);
26 return _type; 38 return _type;
27} 39}
diff --git a/src/compat.h b/src/compat.h
index 8963ef7..d84447b 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -292,6 +292,10 @@ inline int luaG_dump(lua_State* L_, lua_Writer writer_, void* data_, int strip_)
292 292
293// ------------------------------------------------------------------------------------------------- 293// -------------------------------------------------------------------------------------------------
294 294
295int luaG_getalluservalues(lua_State* L_, int idx_);
296
297// -------------------------------------------------------------------------------------------------
298
295LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); 299LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_);
296 300
297// ------------------------------------------------------------------------------------------------- 301// -------------------------------------------------------------------------------------------------
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp
index 8142b6a..b2eda83 100644
--- a/src/intercopycontext.cpp
+++ b/src/intercopycontext.cpp
@@ -653,13 +653,9 @@ void InterCopyContext::inter_copy_keyvaluepair() const
653 int const _mt{ luaG_absindex(L1, -2) }; // L1: ... mt __lanesclone 653 int const _mt{ luaG_absindex(L1, -2) }; // L1: ... mt __lanesclone
654 size_t const userdata_size{ lua_rawlen(L1, _L1_i) }; 654 size_t const userdata_size{ lua_rawlen(L1, _L1_i) };
655 // extract all the uservalues, but don't transfer them yet 655 // extract all the uservalues, but don't transfer them yet
656 int _uvi{ 0 }; 656 int const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]*
657 while (lua_getiuservalue(L1, _L1_i, ++_uvi) != LUA_TNONE) {} // L1: ... mt __lanesclone [uv]+ nil
658 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
659 lua_pop(L1, 1); // L1: ... mt __lanesclone [uv]+
660 --_uvi;
661 // create the clone userdata with the required number of uservalue slots 657 // create the clone userdata with the required number of uservalue slots
662 void* const _clone{ lua_newuserdatauv(L2, userdata_size, _uvi) }; // L2: ... u 658 void* const _clone{ lua_newuserdatauv(L2, userdata_size, _nuv) }; // L2: ... u
663 // copy the metatable in the target state, and give it to the clone we put there 659 // copy the metatable in the target state, and give it to the clone we put there
664 InterCopyContext _c{ U, L2, L1, L2_cache_i, SourceIndex{ _mt }, VT::NORMAL, mode, name }; 660 InterCopyContext _c{ U, L2, L1, L2_cache_i, SourceIndex{ _mt }, VT::NORMAL, mode, name };
665 if (_c.inter_copy_one()) { // L2: ... u mt|sentinel 661 if (_c.inter_copy_one()) { // L2: ... u mt|sentinel
@@ -687,6 +683,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
687 lua_getupvalue(L2, -1, 2); // L2: ... userdata_clone_sentinel u 683 lua_getupvalue(L2, -1, 2); // L2: ... userdata_clone_sentinel u
688 } 684 }
689 // assign uservalues 685 // assign uservalues
686 int _uvi{ _nuv };
690 while (_uvi > 0) { 687 while (_uvi > 0) {
691 _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; 688 _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) };
692 if (!_c.inter_copy_one()) { // L2: ... u uv 689 if (!_c.inter_copy_one()) { // L2: ... u uv
@@ -732,12 +729,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
732 STACK_CHECK_START_REL(L2, 0); 729 STACK_CHECK_START_REL(L2, 0);
733 730
734 // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail 731 // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail
735 int _nuv{ 0 }; 732 int const _nuv{ luaG_getalluservalues(L1, L1_i) }; // L1: ... deep ... [uv]*
736 while (lua_getiuservalue(L1, L1_i, _nuv + 1) != LUA_TNONE) { // L1: ... deep ... [uv]* nil
737 ++_nuv;
738 }
739 // last call returned TNONE and pushed nil, that we don't need
740 lua_pop(L1, 1); // L1: ... deep ... [uv]*
741 STACK_CHECK(L1, _nuv); 733 STACK_CHECK(L1, _nuv);
742 734
743 DeepPrelude* const _deep{ *luaG_tofulluserdata<DeepPrelude*>(L1, L1_i) }; 735 DeepPrelude* const _deep{ *luaG_tofulluserdata<DeepPrelude*>(L1, L1_i) };
@@ -747,16 +739,17 @@ void InterCopyContext::inter_copy_keyvaluepair() const
747 { 739 {
748 InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; 740 InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name };
749 int const _clone_i{ lua_gettop(L2) }; 741 int const _clone_i{ lua_gettop(L2) };
750 // TODO: STACK_GROW(L2, _nuv), and same for L1 above and everywhere we use lua_getiuservalue 742 STACK_GROW(L2, _nuv);
751 while (_nuv) { 743 int _uvi{ _nuv };
744 while (_uvi) {
752 _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; 745 _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) };
753 if (!_c.inter_copy_one()) { // L1: ... deep ... [uv]* L2: deep uv 746 if (!_c.inter_copy_one()) { // L1: ... deep ... [uv]* L2: deep uv
754 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); 747 raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1));
755 } 748 }
756 lua_pop(L1, 1); // L1: ... deep ... [uv]* 749 lua_pop(L1, 1); // L1: ... deep ... [uv]*
757 // this pops the value from the stack 750 // this pops the value from the stack
758 lua_setiuservalue(L2, _clone_i, _nuv); // L2: deep 751 lua_setiuservalue(L2, _clone_i, _uvi); // L2: deep
759 --_nuv; 752 --_uvi;
760 } // loop done: no uv remains on L1 stack // L1: ... deep ... 753 } // loop done: no uv remains on L1 stack // L1: ... deep ...
761 } 754 }
762 755
@@ -818,14 +811,10 @@ void InterCopyContext::inter_copy_keyvaluepair() const
818 size_t const userdata_size{ lua_rawlen(L1, -1) }; 811 size_t const userdata_size{ lua_rawlen(L1, -1) };
819 { 812 {
820 // extract uservalues (don't transfer them yet) 813 // extract uservalues (don't transfer them yet)
821 int _uvi = 0; 814 int const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]*
822 while (lua_getiuservalue(L1, source_i, ++_uvi) != LUA_TNONE) {} // L1: ... u uv 815 STACK_CHECK(L1, _nuv + 1);
823 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
824 lua_pop(L1, 1); // L1: ... u [uv]*
825 --_uvi;
826 STACK_CHECK(L1, _uvi + 1);
827 // create the clone userdata with the required number of uservalue slots 816 // create the clone userdata with the required number of uservalue slots
828 _clone = lua_newuserdatauv(L2, userdata_size, _uvi); // L2: ... mt u 817 _clone = lua_newuserdatauv(L2, userdata_size, _nuv); // L2: ... mt u
829 // add it in the cache 818 // add it in the cache
830 lua_pushlightuserdata(L2, _source); // L2: ... mt u source 819 lua_pushlightuserdata(L2, _source); // L2: ... mt u source
831 lua_pushvalue(L2, -2); // L2: ... mt u source u 820 lua_pushvalue(L2, -2); // L2: ... mt u source u
@@ -835,6 +824,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
835 lua_setmetatable(L2, -2); // L2: ... mt u 824 lua_setmetatable(L2, -2); // L2: ... mt u
836 // transfer and assign uservalues 825 // transfer and assign uservalues
837 InterCopyContext c{ *this }; 826 InterCopyContext c{ *this };
827 int _uvi{ _nuv };
838 while (_uvi > 0) { 828 while (_uvi > 0) {
839 c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; 829 c.L1_i = SourceIndex{ luaG_absindex(L1, -1) };
840 if (!c.inter_copy_one()) { // L2: ... mt u uv 830 if (!c.inter_copy_one()) { // L2: ... mt u uv