diff options
Diffstat (limited to 'src/tools.cpp')
| -rw-r--r-- | src/tools.cpp | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/src/tools.cpp b/src/tools.cpp index 25949e4..aafb9e8 100644 --- a/src/tools.cpp +++ b/src/tools.cpp | |||
| @@ -45,13 +45,33 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; | |||
| 45 | 45 | ||
| 46 | // ################################################################################################# | 46 | // ################################################################################################# |
| 47 | 47 | ||
| 48 | static constexpr int kWriterReturnCode{ 666 }; | 48 | namespace { |
| 49 | [[nodiscard]] | 49 | namespace local { |
| 50 | static int dummy_writer([[maybe_unused]] lua_State* const L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_) | 50 | static int buf_writer(lua_State* L_, void const* b_, size_t size_, void* ud_) |
| 51 | { | 51 | { |
| 52 | // always fail with this code | 52 | auto* const _B{ static_cast<luaL_Buffer*>(ud_) }; |
| 53 | return kWriterReturnCode; | 53 | if (!_B->L) { |
| 54 | } | 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_) { | ||
| 58 | luaL_addlstring(_B, static_cast<char const*>(b_), size_); | ||
| 59 | } | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | static constexpr int kWriterReturnCode{ 666 }; | ||
| 64 | [[nodiscard]] | ||
| 65 | static int dummy_writer([[maybe_unused]] lua_State* const L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_) | ||
| 66 | { | ||
| 67 | // always fail with this code | ||
| 68 | return kWriterReturnCode; | ||
| 69 | } | ||
| 70 | |||
| 71 | } // namespace local | ||
| 72 | } // namespace | ||
| 73 | |||
| 74 | // ################################################################################################# | ||
| 55 | 75 | ||
| 56 | /* | 76 | /* |
| 57 | * differentiation between C, bytecode and JIT-fast functions | 77 | * differentiation between C, bytecode and JIT-fast functions |
| @@ -77,11 +97,11 @@ FuncSubType luaW_getfuncsubtype(lua_State* const L_, StackIndex const i_) | |||
| 77 | // luaW_dump expects the function at the top of the stack | 97 | // luaW_dump expects the function at the top of the stack |
| 78 | int const _popCount{ (luaW_absindex(L_, i_) == lua_gettop(L_)) ? 0 : (lua_pushvalue(L_, i_), 1) }; | 98 | int const _popCount{ (luaW_absindex(L_, i_) == lua_gettop(L_)) ? 0 : (lua_pushvalue(L_, i_), 1) }; |
| 79 | // here we either have a Lua bytecode or a LuaJIT-compiled function | 99 | // here we either have a Lua bytecode or a LuaJIT-compiled function |
| 80 | int const _dumpres{ luaW_dump(L_, dummy_writer, nullptr, 0) }; | 100 | int const _dumpres{ luaW_dump(L_, local::dummy_writer, nullptr, 0) }; |
| 81 | if (_popCount > 0) { | 101 | if (_popCount > 0) { |
| 82 | lua_pop(L_, _popCount); | 102 | lua_pop(L_, _popCount); |
| 83 | } | 103 | } |
| 84 | if (_dumpres == kWriterReturnCode) { | 104 | if (_dumpres == local::kWriterReturnCode) { |
| 85 | // anytime we get kWriterReturnCode, this means that luaW_dump() attempted a dump | 105 | // anytime we get kWriterReturnCode, this means that luaW_dump() attempted a dump |
| 86 | return FuncSubType::Bytecode; | 106 | return FuncSubType::Bytecode; |
| 87 | } | 107 | } |
| @@ -92,7 +112,6 @@ FuncSubType luaW_getfuncsubtype(lua_State* const L_, StackIndex const i_) | |||
| 92 | // ################################################################################################# | 112 | // ################################################################################################# |
| 93 | 113 | ||
| 94 | namespace tools { | 114 | namespace tools { |
| 95 | |||
| 96 | // inspired from tconcat() in ltablib.c | 115 | // inspired from tconcat() in ltablib.c |
| 97 | [[nodiscard]] | 116 | [[nodiscard]] |
| 98 | std::string_view PushFQN(lua_State* const L_, StackIndex const t_) | 117 | std::string_view PushFQN(lua_State* const L_, StackIndex const t_) |
| @@ -118,6 +137,18 @@ namespace tools { | |||
| 118 | return luaW_tostring(L_, kIdxTop); | 137 | return luaW_tostring(L_, kIdxTop); |
| 119 | } | 138 | } |
| 120 | 139 | ||
| 140 | // ############################################################################################# | ||
| 141 | |||
| 142 | [[nodiscard]] | ||
| 143 | int PushFunctionBytecode(lua_State* const L_, int const strip_) | ||
| 144 | { | ||
| 145 | luaL_Buffer B{}; | ||
| 146 | int const result_{ luaW_dump(L_, local::buf_writer, &B, strip_) }; | ||
| 147 | if (result_ == 0) { // documentation says it should always be the case (because our writer only ever returns 0), but better safe than sorry | ||
| 148 | luaL_pushresult(&B); | ||
| 149 | } | ||
| 150 | return result_; | ||
| 151 | } | ||
| 121 | } // namespace tools | 152 | } // namespace tools |
| 122 | 153 | ||
| 123 | // ################################################################################################# | 154 | // ################################################################################################# |
