diff options
-rw-r--r-- | src/compat.h | 124 | ||||
-rw-r--r-- | src/intercopycontext.cpp | 4 | ||||
-rw-r--r-- | src/lanes.cpp | 4 | ||||
-rw-r--r-- | src/nameof.cpp | 2 | ||||
-rw-r--r-- | src/state.cpp | 2 |
5 files changed, 84 insertions, 52 deletions
diff --git a/src/compat.h b/src/compat.h index d84447b..bc8b165 100644 --- a/src/compat.h +++ b/src/compat.h | |||
@@ -26,6 +26,19 @@ extern "C" | |||
26 | #define LUA_JITLIBNAME "jit" | 26 | #define LUA_JITLIBNAME "jit" |
27 | #endif // LUA_JITLIBNAME | 27 | #endif // LUA_JITLIBNAME |
28 | 28 | ||
29 | #ifndef LUA_OK | ||
30 | #define LUA_OK 0 // doesn't exist in Lua 5.1 | ||
31 | #endif // LUA_OK | ||
32 | |||
33 | #ifndef LUA_ERRGCMM | ||
34 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1 and Lua 5.4, we don't care about the actual value | ||
35 | #endif // LUA_ERRGCMM | ||
36 | |||
37 | |||
38 | #ifndef LUA_LOADED_TABLE | ||
39 | #define LUA_LOADED_TABLE "_LOADED" // doesn't exist before Lua 5.3 | ||
40 | #endif // LUA_LOADED_TABLE | ||
41 | |||
29 | // code is now preferring Lua 5.4 API | 42 | // code is now preferring Lua 5.4 API |
30 | 43 | ||
31 | // ################################################################################################# | 44 | // ################################################################################################# |
@@ -46,35 +59,16 @@ enum class LuaType | |||
46 | CDATA = 10 // LuaJIT CDATA | 59 | CDATA = 10 // LuaJIT CDATA |
47 | }; | 60 | }; |
48 | 61 | ||
49 | inline LuaType luaG_type(lua_State* L_, int idx_) | ||
50 | { | ||
51 | return static_cast<LuaType>(lua_type(L_, idx_)); | ||
52 | } | ||
53 | inline char const* luaG_typename(lua_State* L_, LuaType t_) | ||
54 | { | ||
55 | return lua_typename(L_, static_cast<int>(t_)); | ||
56 | } | ||
57 | |||
58 | // ################################################################################################# | 62 | // ################################################################################################# |
59 | 63 | ||
60 | // add some Lua 5.3-style API when building for Lua 5.1 | 64 | // add some Lua 5.3-style API when building for Lua 5.1 |
61 | #if LUA_VERSION_NUM == 501 | 65 | #if LUA_VERSION_NUM == 501 |
62 | 66 | ||
63 | #if LUAJIT_VERSION_NUM < 20200 // moonjit is 5.1 plus bits of 5.2 that we don't need to wrap | ||
64 | inline void lua_pushglobaltable(lua_State* L_) | ||
65 | { | ||
66 | lua_pushvalue(L_, LUA_GLOBALSINDEX); | ||
67 | } | ||
68 | #endif // LUAJIT_VERSION_NUM | ||
69 | inline size_t lua_rawlen(lua_State* L_, int idx_) | 67 | inline size_t lua_rawlen(lua_State* L_, int idx_) |
70 | { | 68 | { |
71 | return lua_objlen(L_, idx_); | 69 | return lua_objlen(L_, idx_); |
72 | } | 70 | } |
73 | // keep as macros to be consistent with Lua headers | ||
74 | #define LUA_OK 0 | ||
75 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value | ||
76 | void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_); // implementation copied from Lua 5.2 sources | 71 | void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_); // implementation copied from Lua 5.2 sources |
77 | #define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.1 | ||
78 | 72 | ||
79 | int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_); | 73 | int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_); |
80 | 74 | ||
@@ -82,28 +76,6 @@ int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_); | |||
82 | 76 | ||
83 | // ################################################################################################# | 77 | // ################################################################################################# |
84 | 78 | ||
85 | // wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way | ||
86 | #if LUA_VERSION_NUM == 502 | ||
87 | |||
88 | #define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.2 | ||
89 | |||
90 | #endif // LUA_VERSION_NUM == 502 | ||
91 | |||
92 | // ################################################################################################# | ||
93 | |||
94 | [[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) | ||
95 | { | ||
96 | // starting with Lua 5.3, lua_getfield returns the type of the value it found | ||
97 | #if LUA_VERSION_NUM < 503 | ||
98 | lua_getfield(L_, idx_, k_.data()); | ||
99 | return luaG_type(L_, -1); | ||
100 | #else // LUA_VERSION_NUM >= 503 | ||
101 | return static_cast<LuaType>(lua_getfield(L_, idx_, k_.data())); | ||
102 | #endif // LUA_VERSION_NUM >= 503 | ||
103 | } | ||
104 | |||
105 | // ################################################################################################# | ||
106 | |||
107 | // wrap Lua 5.3 calls under Lua 5.1 API when it is simpler that way | 79 | // wrap Lua 5.3 calls under Lua 5.1 API when it is simpler that way |
108 | #if LUA_VERSION_NUM == 503 | 80 | #if LUA_VERSION_NUM == 503 |
109 | 81 | ||
@@ -135,7 +107,6 @@ inline int luaL_optint(lua_State* L_, int n_, lua_Integer d_) | |||
135 | { | 107 | { |
136 | return static_cast<int>(luaL_optinteger(L_, n_, d_)); | 108 | return static_cast<int>(luaL_optinteger(L_, n_, d_)); |
137 | } | 109 | } |
138 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.4, we don't care about the actual value | ||
139 | 110 | ||
140 | #endif // LUA_VERSION_NUM == 504 | 111 | #endif // LUA_VERSION_NUM == 504 |
141 | 112 | ||
@@ -149,19 +120,27 @@ enum class LuaError | |||
149 | ERRRUN = LUA_ERRRUN, | 120 | ERRRUN = LUA_ERRRUN, |
150 | ERRSYNTAX = LUA_ERRSYNTAX, | 121 | ERRSYNTAX = LUA_ERRSYNTAX, |
151 | ERRMEM = LUA_ERRMEM, | 122 | ERRMEM = LUA_ERRMEM, |
152 | ERRGCMM = LUA_ERRGCMM, // pre-5.4 | 123 | ERRGCMM = LUA_ERRGCMM, |
153 | ERRERR = LUA_ERRERR, | 124 | ERRERR = LUA_ERRERR, |
154 | ERRFILE = LUA_ERRFILE | 125 | ERRFILE = LUA_ERRFILE |
155 | }; | 126 | }; |
156 | 127 | ||
157 | inline constexpr LuaError ToLuaError(int rc_) | 128 | inline constexpr LuaError ToLuaError(int const rc_) |
158 | { | 129 | { |
159 | assert(rc_ == LUA_OK || rc_ == LUA_YIELD || rc_ == LUA_ERRRUN || rc_ == LUA_ERRSYNTAX || rc_ == LUA_ERRMEM || rc_ == LUA_ERRGCMM || rc_ == LUA_ERRERR); | 130 | assert(rc_ == LUA_OK || rc_ == LUA_YIELD || rc_ == LUA_ERRRUN || rc_ == LUA_ERRSYNTAX || rc_ == LUA_ERRMEM || rc_ == LUA_ERRGCMM || rc_ == LUA_ERRERR || rc_ == LUA_ERRFILE); |
160 | return static_cast<LuaError>(rc_); | 131 | return static_cast<LuaError>(rc_); |
161 | } | 132 | } |
162 | 133 | ||
163 | // ################################################################################################# | 134 | // ################################################################################################# |
164 | 135 | ||
136 | // break lexical order for that one because it's needed below | ||
137 | inline LuaType luaG_type(lua_State* const L_, int const idx_) | ||
138 | { | ||
139 | return static_cast<LuaType>(lua_type(L_, idx_)); | ||
140 | } | ||
141 | |||
142 | // ------------------------------------------------------------------------------------------------- | ||
143 | |||
165 | // Default matches Lua 5.4 as of now | 144 | // Default matches Lua 5.4 as of now |
166 | template <int VERSION, typename SPECIALIZE = void> | 145 | template <int VERSION, typename SPECIALIZE = void> |
167 | struct Wrap | 146 | struct Wrap |
@@ -171,6 +150,12 @@ struct Wrap | |||
171 | return ::lua_dump(L_, writer_, data_, strip_); | 150 | return ::lua_dump(L_, writer_, data_, strip_); |
172 | } | 151 | } |
173 | 152 | ||
153 | static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) | ||
154 | { | ||
155 | // starting with Lua 5.3, lua_getfield returns the type of the pushed value | ||
156 | return static_cast<LuaType>(::lua_getfield(L_, idx_, k_.data())); | ||
157 | } | ||
158 | |||
174 | template <size_t N> | 159 | template <size_t N> |
175 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | 160 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) |
176 | { | 161 | { |
@@ -199,6 +184,12 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 503>::type> | |||
199 | return ::lua_dump(L_, writer_, data_, strip_); | 184 | return ::lua_dump(L_, writer_, data_, strip_); |
200 | } | 185 | } |
201 | 186 | ||
187 | static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) | ||
188 | { | ||
189 | // starting with Lua 5.3, lua_getfield returns the type of the pushed value | ||
190 | return static_cast<LuaType>(::lua_getfield(L_, idx_, k_.data())); | ||
191 | } | ||
192 | |||
202 | template <size_t N> | 193 | template <size_t N> |
203 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | 194 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) |
204 | { | 195 | { |
@@ -227,10 +218,17 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 502>::type> | |||
227 | return ::lua_dump(L_, writer_, data_); | 218 | return ::lua_dump(L_, writer_, data_); |
228 | } | 219 | } |
229 | 220 | ||
221 | static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) | ||
222 | { | ||
223 | // before Lua 5.3, lua_getfield returns nothing | ||
224 | ::lua_getfield(L_, idx_, k_.data()); | ||
225 | return luaG_type(L_, -1); | ||
226 | } | ||
227 | |||
230 | template <size_t N> | 228 | template <size_t N> |
231 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | 229 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) |
232 | { | 230 | { |
233 | lua_createtable(L_, 0, N - 1); | 231 | ::lua_createtable(L_, 0, N - 1); |
234 | ::luaL_setfuncs(L_, funcs_, 0); | 232 | ::luaL_setfuncs(L_, funcs_, 0); |
235 | } | 233 | } |
236 | 234 | ||
@@ -255,6 +253,13 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 501>::type> | |||
255 | return ::lua_dump(L_, writer_, data_); | 253 | return ::lua_dump(L_, writer_, data_); |
256 | } | 254 | } |
257 | 255 | ||
256 | static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) | ||
257 | { | ||
258 | // before Lua 5.3, lua_getfield returns nothing | ||
259 | ::lua_getfield(L_, idx_, k_.data()); | ||
260 | return luaG_type(L_, -1); | ||
261 | } | ||
262 | |||
258 | template<size_t N> | 263 | template<size_t N> |
259 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | 264 | static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) |
260 | { | 265 | { |
@@ -277,6 +282,8 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 501>::type> | |||
277 | // ################################################################################################# | 282 | // ################################################################################################# |
278 | // All the compatibility wrappers we expose start with luaG_ | 283 | // All the compatibility wrappers we expose start with luaG_ |
279 | 284 | ||
285 | // ------------------------------------------------------------------------------------------------- | ||
286 | |||
280 | // use this in place of lua_absindex to save a function call | 287 | // use this in place of lua_absindex to save a function call |
281 | inline int luaG_absindex(lua_State* L_, int idx_) | 288 | inline int luaG_absindex(lua_State* L_, int idx_) |
282 | { | 289 | { |
@@ -296,6 +303,13 @@ int luaG_getalluservalues(lua_State* L_, int idx_); | |||
296 | 303 | ||
297 | // ------------------------------------------------------------------------------------------------- | 304 | // ------------------------------------------------------------------------------------------------- |
298 | 305 | ||
306 | [[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) | ||
307 | { | ||
308 | return Wrap<LUA_VERSION_NUM>::lua_getfield(L_, idx_, k_); | ||
309 | } | ||
310 | |||
311 | // ------------------------------------------------------------------------------------------------- | ||
312 | |||
299 | LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); | 313 | LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); |
300 | 314 | ||
301 | // ------------------------------------------------------------------------------------------------- | 315 | // ------------------------------------------------------------------------------------------------- |
@@ -316,6 +330,17 @@ template <typename T> | |||
316 | 330 | ||
317 | // ------------------------------------------------------------------------------------------------- | 331 | // ------------------------------------------------------------------------------------------------- |
318 | 332 | ||
333 | inline void luaG_pushglobaltable(lua_State* const L_) | ||
334 | { | ||
335 | #ifdef LUA_GLOBALSINDEX // All flavors of Lua 5.1 | ||
336 | ::lua_pushvalue(L_, LUA_GLOBALSINDEX); | ||
337 | #else // LUA_GLOBALSINDEX | ||
338 | ::lua_rawgeti(L_, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); | ||
339 | #endif // LUA_GLOBALSINDEX | ||
340 | } | ||
341 | |||
342 | // ------------------------------------------------------------------------------------------------- | ||
343 | |||
319 | inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) | 344 | inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) |
320 | { | 345 | { |
321 | Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0); | 346 | Wrap<LUA_VERSION_NUM>::luaL_setfuncs(L_, funcs_, 0); |
@@ -351,6 +376,13 @@ template <typename T> | |||
351 | } | 376 | } |
352 | } | 377 | } |
353 | 378 | ||
379 | // ------------------------------------------------------------------------------------------------- | ||
380 | |||
381 | inline char const* luaG_typename(lua_State* L_, LuaType t_) | ||
382 | { | ||
383 | return lua_typename(L_, static_cast<int>(t_)); | ||
384 | } | ||
385 | |||
354 | // ################################################################################################# | 386 | // ################################################################################################# |
355 | 387 | ||
356 | // must keep as a macro as long as we do constant string concatenations | 388 | // must keep as a macro as long as we do constant string concatenations |
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index b2eda83..fcec38a 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -262,12 +262,12 @@ void InterCopyContext::copy_func() const | |||
262 | { | 262 | { |
263 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; | 263 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; |
264 | // if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table | 264 | // if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table |
265 | lua_pushglobaltable(L1); // L1: ... _G | 265 | luaG_pushglobaltable(L1); // L1: ... _G |
266 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] | 266 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] |
267 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); | 267 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); |
268 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? | 268 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? |
269 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); | 269 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); |
270 | lua_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> | 270 | luaG_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> |
271 | } else { | 271 | } else { |
272 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); | 272 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); |
273 | _c.L1_i = SourceIndex{ lua_gettop(L1) }; | 273 | _c.L1_i = SourceIndex{ lua_gettop(L1) }; |
diff --git a/src/lanes.cpp b/src/lanes.cpp index a7631bb..b7cd148 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -466,7 +466,7 @@ LUAG_FUNC(lane_new) | |||
466 | lua_pushnil(L_); // L_: [fixed] args... nil L2: | 466 | lua_pushnil(L_); // L_: [fixed] args... nil L2: |
467 | // Lua 5.2 wants us to push the globals table on the stack | 467 | // Lua 5.2 wants us to push the globals table on the stack |
468 | InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; | 468 | InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; |
469 | lua_pushglobaltable(_L2); // L_: [fixed] args... nil L2: _G | 469 | luaG_pushglobaltable(_L2); // L_: [fixed] args... nil L2: _G |
470 | while (lua_next(L_, _globals_idx)) { // L_: [fixed] args... k v L2: _G | 470 | while (lua_next(L_, _globals_idx)) { // L_: [fixed] args... k v L2: _G |
471 | std::ignore = _c.inter_copy(2); // L_: [fixed] args... k v L2: _G k v | 471 | std::ignore = _c.inter_copy(2); // L_: [fixed] args... k v L2: _G k v |
472 | // assign it in L2's globals table | 472 | // assign it in L2's globals table |
@@ -740,7 +740,7 @@ LUAG_FUNC(configure) | |||
740 | // don't do this when called during the initialization of a new lane, | 740 | // don't do this when called during the initialization of a new lane, |
741 | // because we will do it after on_state_create() is called, | 741 | // because we will do it after on_state_create() is called, |
742 | // and we don't want to skip _G because of caching in case globals are created then | 742 | // and we don't want to skip _G because of caching in case globals are created then |
743 | lua_pushglobaltable(L_); // L_: settings M _G | 743 | luaG_pushglobaltable(L_); // L_: settings M _G |
744 | tools::PopulateFuncLookupTable(L_, -1, {}); | 744 | tools::PopulateFuncLookupTable(L_, -1, {}); |
745 | lua_pop(L_, 1); // L_: settings M | 745 | lua_pop(L_, 1); // L_: settings M |
746 | } | 746 | } |
diff --git a/src/nameof.cpp b/src/nameof.cpp index 6c968d5..543c3d4 100644 --- a/src/nameof.cpp +++ b/src/nameof.cpp | |||
@@ -191,7 +191,7 @@ LUAG_FUNC(nameof) | |||
191 | lua_pushliteral(L_, LUA_GNAME); // L_: o nil {c} {fqn} "_G" | 191 | lua_pushliteral(L_, LUA_GNAME); // L_: o nil {c} {fqn} "_G" |
192 | lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} | 192 | lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} |
193 | // this is where we start the search | 193 | // this is where we start the search |
194 | lua_pushglobaltable(L_); // L_: o nil {c} {fqn} _G | 194 | luaG_pushglobaltable(L_); // L_: o nil {c} {fqn} _G |
195 | std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits<int>::max(), 1); | 195 | std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits<int>::max(), 1); |
196 | if (lua_isnil(L_, 2)) { // try again with registry, just in case... | 196 | if (lua_isnil(L_, 2)) { // try again with registry, just in case... |
197 | lua_pop(L_, 1); // L_: o nil {c} {fqn} | 197 | lua_pop(L_, 1); // L_: o nil {c} {fqn} |
diff --git a/src/state.cpp b/src/state.cpp index cafabf1..77e1fd9 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
@@ -352,7 +352,7 @@ namespace state { | |||
352 | 352 | ||
353 | STACK_CHECK(_L, 0); | 353 | STACK_CHECK(_L, 0); |
354 | // after all this, register everything we find in our name<->function database | 354 | // after all this, register everything we find in our name<->function database |
355 | lua_pushglobaltable(_L); // L: _G | 355 | luaG_pushglobaltable(_L); // L: _G |
356 | tools::PopulateFuncLookupTable(_L, -1, {}); | 356 | tools::PopulateFuncLookupTable(_L, -1, {}); |
357 | lua_pop(_L, 1); // L: | 357 | lua_pop(_L, 1); // L: |
358 | STACK_CHECK(_L, 0); | 358 | STACK_CHECK(_L, 0); |