aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compat.h124
-rw-r--r--src/intercopycontext.cpp4
-rw-r--r--src/lanes.cpp4
-rw-r--r--src/nameof.cpp2
-rw-r--r--src/state.cpp2
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
49inline LuaType luaG_type(lua_State* L_, int idx_)
50{
51 return static_cast<LuaType>(lua_type(L_, idx_));
52}
53inline 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
64inline void lua_pushglobaltable(lua_State* L_)
65{
66 lua_pushvalue(L_, LUA_GLOBALSINDEX);
67}
68#endif // LUAJIT_VERSION_NUM
69inline size_t lua_rawlen(lua_State* L_, int idx_) 67inline 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
76void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_); // implementation copied from Lua 5.2 sources 71void 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
79int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_); 73int 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
157inline constexpr LuaError ToLuaError(int rc_) 128inline 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
137inline 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
166template <int VERSION, typename SPECIALIZE = void> 145template <int VERSION, typename SPECIALIZE = void>
167struct Wrap 146struct 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
281inline int luaG_absindex(lua_State* L_, int idx_) 288inline 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
299LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); 313LuaType 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
333inline 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
319inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) 344inline 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
381inline 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);