aboutsummaryrefslogtreecommitdiff
path: root/src/tools.cpp
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2025-07-24 16:51:49 +0200
committerBenoit Germain <bnt.germain@gmail.com>2025-07-24 16:51:49 +0200
commitd8acb18ce8bf6e89a042d166f61b2934e8722cf0 (patch)
tree69f5046056f4aa38b868b057055da8144e029846 /src/tools.cpp
parenteb997664a5a0a7890efa050982854a1447aec70f (diff)
downloadlanes-d8acb18ce8bf6e89a042d166f61b2934e8722cf0.tar.gz
lanes-d8acb18ce8bf6e89a042d166f61b2934e8722cf0.tar.bz2
lanes-d8acb18ce8bf6e89a042d166f61b2934e8722cf0.zip
Rework function bytecode dumping to be Lua5.5-ready
* prepare the luaL_Buffer in the destination state instead of the source state to prevent stack issues when everything happens in the same state
Diffstat (limited to 'src/tools.cpp')
-rw-r--r--src/tools.cpp31
1 files changed, 11 insertions, 20 deletions
diff --git a/src/tools.cpp b/src/tools.cpp
index c6e9cc3..cd1c593 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -47,13 +47,9 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull };
47 47
48namespace { 48namespace {
49 namespace local { 49 namespace local {
50 static int buf_writer(lua_State* L_, void const* b_, size_t size_, void* ud_) 50 static int buf_writer([[maybe_unused]] lua_State* const L_, void const* b_, size_t size_, void* ud_)
51 { 51 {
52 auto* const _B{ static_cast<luaL_Buffer*>(ud_) }; 52 auto* const _B{ static_cast<luaL_Buffer*>(ud_) };
53 if (!_B->L) {
54 luaL_buffinit(L_, _B);
55 }
56 // starting with Lua 5.5, the writer is called one last time with nullptr, 0 at the end
57 if (b_ && size_) { 53 if (b_ && size_) {
58 luaL_addlstring(_B, static_cast<char const*>(b_), size_); 54 luaL_addlstring(_B, static_cast<char const*>(b_), size_);
59 } 55 }
@@ -79,9 +75,7 @@ namespace {
79 * +-------------------+------------+----------+ 75 * +-------------------+------------+----------+
80 * | bytecode | C function | JIT-fast | 76 * | bytecode | C function | JIT-fast |
81 * +-----------------+-------------------+------------+----------+ 77 * +-----------------+-------------------+------------+----------+
82 * | lua_topointer | | | | 78 * | lua_tocfunction | nullptr | <some p> | nullptr |
83 * +-----------------+-------------------+------------+----------+
84 * | lua_tocfunction | nullptr | | nullptr |
85 * +-----------------+-------------------+------------+----------+ 79 * +-----------------+-------------------+------------+----------+
86 * | luaW_dump | kWriterReturnCode | 1 | 1 | 80 * | luaW_dump | kWriterReturnCode | 1 | 1 |
87 * +-----------------+-------------------+------------+----------+ 81 * +-----------------+-------------------+------------+----------+
@@ -139,20 +133,17 @@ namespace tools {
139 133
140 // ############################################################################################# 134 // #############################################################################################
141 135
142 [[nodiscard]] 136 void PushFunctionBytecode(SourceState const L1_, DestState const L2_, int const strip_)
143 int PushFunctionBytecode(lua_State* const L_, int const strip_)
144 { 137 {
145 luaL_Buffer B{}; 138 luaL_Buffer B{};
146 // WORKAROUND FOR Lua 5.5 beta: lua_dump followed by luaL_pushresult pops the function from the stack before adding the bytecode string 139 STACK_CHECK_START_REL(L1_, 0);
147 // so I need to duplicate it so that I end up with the original stack and the bytecode string pushed on top 140 STACK_CHECK_START_REL(L2_, 0);
148 if constexpr (LUA_VERSION_NUM == 505) { 141 STACK_GROW(L2_, 2);
149 lua_pushvalue(L_, kIdxTop); 142 luaL_buffinit(L2_, &B); // L1_: ... f L2_: ... <B stuff>
150 } 143 luaW_dump(L1_, local::buf_writer, &B, strip_);
151 int const result_{ luaW_dump(L_, local::buf_writer, &B, strip_) }; 144 luaL_pushresult(&B); // L2_: ... "<bytecode>"
152 if (result_ == 0) { // documentation says it should always be the case (because our writer only ever returns 0), but better safe than sorry 145 STACK_CHECK(L2_, 1);
153 luaL_pushresult(&B); 146 STACK_CHECK(L1_, 0);
154 }
155 return result_;
156 } 147 }
157} // namespace tools 148} // namespace tools
158 149