aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cancel.cpp86
-rw-r--r--src/cancel.h8
-rw-r--r--src/compat.cpp86
-rw-r--r--src/compat.h6
-rw-r--r--src/deep.cpp92
-rw-r--r--src/keeper.cpp472
-rw-r--r--src/keeper.h22
-rw-r--r--src/lanes.cpp823
-rw-r--r--src/lanes.h6
-rw-r--r--src/lanes_private.h4
-rw-r--r--src/linda.cpp256
-rw-r--r--src/linda.h2
-rw-r--r--src/lindafactory.cpp2
-rw-r--r--src/macros_and_utils.h28
-rw-r--r--src/state.cpp102
-rw-r--r--src/state.h6
-rw-r--r--src/tools.cpp635
-rw-r--r--src/tools.h10
-rw-r--r--src/universe.cpp32
-rw-r--r--src/universe.h24
20 files changed, 1345 insertions, 1357 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp
index cff1443..82c6def 100644
--- a/src/cancel.cpp
+++ b/src/cancel.cpp
@@ -51,9 +51,9 @@ THE SOFTWARE.
51* Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'raise_cancel_error()' called, 51* Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'raise_cancel_error()' called,
52* to make execution of the lane end. 52* to make execution of the lane end.
53*/ 53*/
54[[nodiscard]] static inline CancelRequest cancel_test(lua_State* L) 54[[nodiscard]] static inline CancelRequest cancel_test(lua_State* L_)
55{ 55{
56 Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L) }; 56 Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) };
57 // 'lane' is nullptr for the original main state (and no-one can cancel that) 57 // 'lane' is nullptr for the original main state (and no-one can cancel that)
58 return lane ? lane->cancel_request : CancelRequest::None; 58 return lane ? lane->cancel_request : CancelRequest::None;
59} 59}
@@ -68,21 +68,21 @@ THE SOFTWARE.
68// 68//
69LUAG_FUNC(cancel_test) 69LUAG_FUNC(cancel_test)
70{ 70{
71 CancelRequest test{ cancel_test(L) }; 71 CancelRequest test{ cancel_test(L_) };
72 lua_pushboolean(L, test != CancelRequest::None); 72 lua_pushboolean(L_, test != CancelRequest::None);
73 return 1; 73 return 1;
74} 74}
75 75
76// ################################################################################################# 76// #################################################################################################
77// ################################################################################################# 77// #################################################################################################
78 78
79[[nodiscard]] static void cancel_hook(lua_State* L, [[maybe_unused]] lua_Debug* ar) 79[[nodiscard]] static void cancel_hook(lua_State* L_, [[maybe_unused]] lua_Debug* ar)
80{ 80{
81 DEBUGSPEW_CODE(fprintf(stderr, "cancel_hook\n")); 81 DEBUGSPEW_CODE(fprintf(stderr, "cancel_hook\n"));
82 if (cancel_test(L) != CancelRequest::None) 82 if (cancel_test(L_) != CancelRequest::None)
83 { 83 {
84 lua_sethook(L, nullptr, 0, 0); 84 lua_sethook(L_, nullptr, 0, 0);
85 raise_cancel_error(L); 85 raise_cancel_error(L_);
86 } 86 }
87} 87}
88 88
@@ -204,16 +204,16 @@ CancelOp which_cancel_op(char const* op_string_)
204 204
205// ################################################################################################# 205// #################################################################################################
206 206
207[[nodiscard]] static CancelOp which_cancel_op(lua_State* L, int idx_) 207[[nodiscard]] static CancelOp which_cancel_op(lua_State* L_, int idx_)
208{ 208{
209 if (lua_type(L, idx_) == LUA_TSTRING) 209 if (lua_type(L_, idx_) == LUA_TSTRING)
210 { 210 {
211 char const* const str{ lua_tostring(L, idx_) }; 211 char const* const str{ lua_tostring(L_, idx_) };
212 CancelOp op{ which_cancel_op(str) }; 212 CancelOp op{ which_cancel_op(str) };
213 lua_remove(L, idx_); // argument is processed, remove it 213 lua_remove(L_, idx_); // argument is processed, remove it
214 if (op == CancelOp::Invalid) 214 if (op == CancelOp::Invalid)
215 { 215 {
216 raise_luaL_error(L, "invalid hook option %s", str); 216 raise_luaL_error(L_, "invalid hook option %s", str);
217 } 217 }
218 return op; 218 return op;
219 } 219 }
@@ -225,58 +225,52 @@ CancelOp which_cancel_op(char const* op_string_)
225// bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, wake_lindas]) 225// bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, wake_lindas])
226LUAG_FUNC(thread_cancel) 226LUAG_FUNC(thread_cancel)
227{ 227{
228 Lane* const lane{ ToLane(L, 1) }; 228 Lane* const lane{ ToLane(L_, 1) };
229 CancelOp const op{ which_cancel_op(L, 2) }; // this removes the op string from the stack 229 CancelOp const op{ which_cancel_op(L_, 2) }; // this removes the op string from the stack
230 230
231 int hook_count{ 0 }; 231 int hook_count{ 0 };
232 if (static_cast<int>(op) > static_cast<int>(CancelOp::Soft)) // hook is requested 232 if (static_cast<int>(op) > static_cast<int>(CancelOp::Soft)) // hook is requested
233 { 233 {
234 hook_count = static_cast<int>(luaL_checkinteger(L, 2)); 234 hook_count = static_cast<int>(luaL_checkinteger(L_, 2));
235 lua_remove(L, 2); // argument is processed, remove it 235 lua_remove(L_, 2); // argument is processed, remove it
236 if (hook_count < 1) 236 if (hook_count < 1) {
237 { 237 raise_luaL_error(L_, "hook count cannot be < 1");
238 raise_luaL_error(L, "hook count cannot be < 1");
239 } 238 }
240 } 239 }
241 240
242 lua_Duration wait_timeout{ 0.0 }; 241 lua_Duration wait_timeout{ 0.0 };
243 if (lua_type(L, 2) == LUA_TNUMBER) 242 if (lua_type(L_, 2) == LUA_TNUMBER) {
244 { 243 wait_timeout = lua_Duration{ lua_tonumber(L_, 2) };
245 wait_timeout = lua_Duration{ lua_tonumber(L, 2) }; 244 lua_remove(L_, 2); // argument is processed, remove it
246 lua_remove(L, 2); // argument is processed, remove it 245 if (wait_timeout.count() < 0.0) {
247 if (wait_timeout.count() < 0.0) 246 raise_luaL_error(L_, "cancel timeout cannot be < 0");
248 {
249 raise_luaL_error(L, "cancel timeout cannot be < 0");
250 } 247 }
251 } 248 }
252 // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired 249 // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired
253 bool wake_lane{ op != CancelOp::Soft }; 250 bool wake_lane{ op != CancelOp::Soft };
254 if (lua_gettop(L) >= 2) 251 if (lua_gettop(L_) >= 2) {
255 { 252 if (!lua_isboolean(L_, 2)) {
256 if (!lua_isboolean(L, 2)) 253 raise_luaL_error(L_, "wake_lindas parameter is not a boolean");
257 {
258 raise_luaL_error(L, "wake_lindas parameter is not a boolean");
259 } 254 }
260 wake_lane = lua_toboolean(L, 2); 255 wake_lane = lua_toboolean(L_, 2);
261 lua_remove(L, 2); // argument is processed, remove it 256 lua_remove(L_, 2); // argument is processed, remove it
262 } 257 }
263 STACK_CHECK_START_REL(L, 0); 258 STACK_CHECK_START_REL(L_, 0);
264 switch (thread_cancel(lane, op, hook_count, wait_timeout, wake_lane)) 259 switch (thread_cancel(lane, op, hook_count, wait_timeout, wake_lane)) {
265 { 260 default: // should never happen unless we added a case and forgot to handle it
266 default: // should never happen unless we added a case and forgot to handle it 261 LUA_ASSERT(L_, false);
267 LUA_ASSERT(L, false);
268 break; 262 break;
269 263
270 case CancelResult::Timeout: 264 case CancelResult::Timeout:
271 lua_pushboolean(L, 0); // false 265 lua_pushboolean(L_, 0); // false
272 lua_pushstring(L, "timeout"); // false "timeout" 266 lua_pushstring(L_, "timeout"); // false "timeout"
273 break; 267 break;
274 268
275 case CancelResult::Cancelled: 269 case CancelResult::Cancelled:
276 lua_pushboolean(L, 1); // true 270 lua_pushboolean(L_, 1); // true
277 lane->pushThreadStatus(L); // true status 271 lane->pushThreadStatus(L_); // true status
278 break; 272 break;
279 } 273 }
280 STACK_CHECK(L, 2); 274 STACK_CHECK(L_, 2);
281 return 2; 275 return 2;
282} 276}
diff --git a/src/cancel.h b/src/cancel.h
index 8c8063f..59ebefe 100644
--- a/src/cancel.h
+++ b/src/cancel.h
@@ -51,11 +51,11 @@ static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_er
51[[nodiscard]] CancelOp which_cancel_op(char const* op_string_); 51[[nodiscard]] CancelOp which_cancel_op(char const* op_string_);
52[[nodiscard]] CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hook_count_, lua_Duration secs_, bool wake_lindas_); 52[[nodiscard]] CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hook_count_, lua_Duration secs_, bool wake_lindas_);
53 53
54[[noreturn]] static inline void raise_cancel_error(lua_State* L) 54[[noreturn]] static inline void raise_cancel_error(lua_State* L_)
55{ 55{
56 STACK_GROW(L, 1); 56 STACK_GROW(L_, 1);
57 kCancelError.pushKey(L); // special error value 57 kCancelError.pushKey(L_); // special error value
58 raise_lua_error(L); 58 raise_lua_error(L_);
59} 59}
60 60
61// ################################################################################################# 61// #################################################################################################
diff --git a/src/compat.cpp b/src/compat.cpp
index 712aa23..41a206a 100644
--- a/src/compat.cpp
+++ b/src/compat.cpp
@@ -12,37 +12,35 @@
12// ################################################################################################# 12// #################################################################################################
13 13
14// Copied from Lua 5.2 loadlib.c 14// Copied from Lua 5.2 loadlib.c
15static int luaL_getsubtable(lua_State* L, int idx, const char* fname) 15static int luaL_getsubtable(lua_State* L_, int idx, const char* fname)
16{ 16{
17 lua_getfield(L, idx, fname); 17 lua_getfield(L_, idx, fname);
18 if (lua_istable(L, -1)) 18 if (lua_istable(L_, -1))
19 return 1; /* table already there */ 19 return 1; /* table already there */
20 else 20 else {
21 { 21 lua_pop(L_, 1); /* remove previous result */
22 lua_pop(L, 1); /* remove previous result */ 22 idx = lua_absindex(L_, idx);
23 idx = lua_absindex(L, idx); 23 lua_newtable(L_);
24 lua_newtable(L); 24 lua_pushvalue(L_, -1); /* copy to be left at top */
25 lua_pushvalue(L, -1); /* copy to be left at top */ 25 lua_setfield(L_, idx, fname); /* assign new table to field */
26 lua_setfield(L, idx, fname); /* assign new table to field */ 26 return 0; /* false, because did not find table there */
27 return 0; /* false, because did not find table there */
28 } 27 }
29} 28}
30 29
31// ################################################################################################# 30// #################################################################################################
32 31
33void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) 32void luaL_requiref(lua_State* L_, const char* modname, lua_CFunction openf, int glb)
34{ 33{
35 lua_pushcfunction(L, openf); 34 lua_pushcfunction(L_, openf);
36 lua_pushstring(L, modname); /* argument to open function */ 35 lua_pushstring(L_, modname); /* argument to open function */
37 lua_call(L, 1, 1); /* open module */ 36 lua_call(L_, 1, 1); /* open module */
38 luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); 37 luaL_getsubtable(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
39 lua_pushvalue(L, -2); /* make copy of module (call result) */ 38 lua_pushvalue(L_, -2); /* make copy of module (call result) */
40 lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ 39 lua_setfield(L_, -2, modname); /* _LOADED[modname] = module */
41 lua_pop(L, 1); /* remove _LOADED table */ 40 lua_pop(L_, 1); /* remove _LOADED table */
42 if (glb) 41 if (glb) {
43 { 42 lua_pushvalue(L_, -1); /* copy of 'mod' */
44 lua_pushvalue(L, -1); /* copy of 'mod' */ 43 lua_setglobal(L_, modname); /* _G[modname] = module */
45 lua_setglobal(L, modname); /* _G[modname] = module */
46 } 44 }
47} 45}
48#endif // LUA_VERSION_NUM 46#endif // LUA_VERSION_NUM
@@ -53,60 +51,56 @@ void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int g
53// ################################################################################################# 51// #################################################################################################
54// ################################################################################################# 52// #################################################################################################
55 53
56void* lua_newuserdatauv( lua_State* L, size_t sz, int nuvalue) 54void* lua_newuserdatauv(lua_State* L_, size_t sz, int nuvalue)
57{ 55{
58 LUA_ASSERT(L, nuvalue <= 1); 56 LUA_ASSERT(L_, nuvalue <= 1);
59 return lua_newuserdata(L, sz); 57 return lua_newuserdata(L_, sz);
60} 58}
61 59
62// ################################################################################################# 60// #################################################################################################
63 61
64// push on stack uservalue #n of full userdata at idx 62// push on stack uservalue #n of full userdata at idx
65int lua_getiuservalue(lua_State* L, int idx, int n) 63int lua_getiuservalue(lua_State* L_, int idx, int n)
66{ 64{
67 // full userdata can have only 1 uservalue before 5.4 65 // full userdata can have only 1 uservalue before 5.4
68 if (n > 1) 66 if (n > 1) {
69 { 67 lua_pushnil(L_);
70 lua_pushnil(L);
71 return LUA_TNONE; 68 return LUA_TNONE;
72 } 69 }
73 lua_getuservalue(L, idx); 70 lua_getuservalue(L_, idx);
74 71
75#if LUA_VERSION_NUM == 501 72#if LUA_VERSION_NUM == 501
76 /* default environment is not a nil (see lua_getfenv) */ 73 /* default environment is not a nil (see lua_getfenv) */
77 lua_getglobal(L, "package"); 74 lua_getglobal(L_, "package");
78 if (lua_rawequal(L, -2, -1) || lua_rawequal(L, -2, LUA_GLOBALSINDEX)) 75 if (lua_rawequal(L_, -2, -1) || lua_rawequal(L_, -2, LUA_GLOBALSINDEX)) {
79 { 76 lua_pop(L_, 2);
80 lua_pop(L, 2); 77 lua_pushnil(L_);
81 lua_pushnil(L);
82 78
83 return LUA_TNONE; 79 return LUA_TNONE;
84 } 80 }
85 lua_pop(L, 1); /* remove package */ 81 lua_pop(L_, 1); /* remove package */
86#endif 82#endif
87 83
88 return lua_type(L, -1); 84 return lua_type(L_, -1);
89} 85}
90 86
91// ################################################################################################# 87// #################################################################################################
92 88
93// Pops a value from the stack and sets it as the new n-th user value associated to the full userdata at the given index. 89// Pops a value from the stack and sets it as the new n-th user value associated to the full userdata at the given index.
94// Returns 0 if the userdata does not have that value. 90// Returns 0 if the userdata does not have that value.
95int lua_setiuservalue(lua_State* L, int idx, int n) 91int lua_setiuservalue(lua_State* L_, int idx, int n)
96{ 92{
97 if (n > 1 93 if (n > 1
98#if LUA_VERSION_NUM == 501 94#if LUA_VERSION_NUM == 501
99 || lua_type(L, -1) != LUA_TTABLE 95 || lua_type(L_, -1) != LUA_TTABLE
100#endif 96#endif
101 ) 97 ) {
102 { 98 lua_pop(L_, 1);
103 lua_pop(L, 1);
104 return 0; 99 return 0;
105 } 100 }
106 101
107 lua_setuservalue(L, idx); 102 lua_setuservalue(L_, idx);
108 return 1; // I guess anything non-0 is ok 103 return 1; // I guess anything non-0 is ok
109} 104}
110 105
111#endif // LUA_VERSION_NUM 106#endif // LUA_VERSION_NUM
112
diff --git a/src/compat.h b/src/compat.h
index 037a3ba..a7ad1f3 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -36,11 +36,11 @@ extern "C"
36#define lua_setuservalue lua_setfenv 36#define lua_setuservalue lua_setfenv
37#define lua_getuservalue lua_getfenv 37#define lua_getuservalue lua_getfenv
38#define lua_rawlen lua_objlen 38#define lua_rawlen lua_objlen
39#define luaG_registerlibfuncs(L, _funcs) luaL_register(L, nullptr, _funcs) 39#define luaG_registerlibfuncs(L_, _funcs) luaL_register(L_, nullptr, _funcs)
40#define LUA_OK 0 40#define LUA_OK 0
41#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value 41#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value
42void luaL_requiref(lua_State* L, const char* modname, lua_CFunction openf, int glb); // implementation copied from Lua 5.2 sources 42void luaL_requiref(lua_State* L_, const char* modname, lua_CFunction openf, int glb); // implementation copied from Lua 5.2 sources
43#define lua504_dump(L, writer, data, strip) lua_dump(L, writer, data) 43#define lua504_dump(L_, writer_, data_, strip_) lua_dump(L_, writer_, data_)
44#define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.1 44#define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.1
45 45
46#endif // LUA_VERSION_NUM == 501 46#endif // LUA_VERSION_NUM == 501
diff --git a/src/deep.cpp b/src/deep.cpp
index 5a62000..10f589e 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -66,19 +66,19 @@ static constexpr RegistryUniqueKey kDeepProxyCacheRegKey{ 0xEBCD49AE1A3DD35Eull
66* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 66* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
67* Pops the both values off the stack. 67* Pops the both values off the stack.
68*/ 68*/
69static void set_deep_lookup(lua_State* L) 69static void set_deep_lookup(lua_State* L_)
70{ 70{
71 STACK_GROW( L, 3); 71 STACK_GROW( L_, 3);
72 STACK_CHECK_START_REL(L, 2); // a b 72 STACK_CHECK_START_REL(L_, 2); // a b
73 push_registry_subtable( L, kDeepLookupRegKey); // a b {} 73 push_registry_subtable( L_, kDeepLookupRegKey); // a b {}
74 STACK_CHECK( L, 3); 74 STACK_CHECK( L_, 3);
75 lua_insert( L, -3); // {} a b 75 lua_insert( L_, -3); // {} a b
76 lua_pushvalue( L, -1); // {} a b b 76 lua_pushvalue( L_, -1); // {} a b b
77 lua_pushvalue( L,-3); // {} a b b a 77 lua_pushvalue( L_,-3); // {} a b b a
78 lua_rawset( L, -5); // {} a b 78 lua_rawset( L_, -5); // {} a b
79 lua_rawset( L, -3); // {} 79 lua_rawset( L_, -3); // {}
80 lua_pop( L, 1); // 80 lua_pop( L_, 1); //
81 STACK_CHECK( L, 0); 81 STACK_CHECK( L_, 0);
82} 82}
83 83
84// ################################################################################################# 84// #################################################################################################
@@ -87,18 +87,18 @@ static void set_deep_lookup(lua_State* L)
87* Pops the key (metatable or factory) off the stack, and replaces with the 87* Pops the key (metatable or factory) off the stack, and replaces with the
88* deep lookup value (factory/metatable/nil). 88* deep lookup value (factory/metatable/nil).
89*/ 89*/
90static void get_deep_lookup(lua_State* L) 90static void get_deep_lookup(lua_State* L_)
91{ 91{
92 STACK_GROW( L, 1); 92 STACK_GROW( L_, 1);
93 STACK_CHECK_START_REL(L, 1); // a 93 STACK_CHECK_START_REL(L_, 1); // a
94 kDeepLookupRegKey.pushValue(L); // a {} 94 kDeepLookupRegKey.pushValue(L_); // a {}
95 if (!lua_isnil( L, -1)) 95 if (!lua_isnil( L_, -1))
96 { 96 {
97 lua_insert( L, -2); // {} a 97 lua_insert( L_, -2); // {} a
98 lua_rawget( L, -2); // {} b 98 lua_rawget( L_, -2); // {} b
99 } 99 }
100 lua_remove( L, -2); // a|b 100 lua_remove( L_, -2); // a|b
101 STACK_CHECK( L, 1); 101 STACK_CHECK( L_, 1);
102} 102}
103 103
104// ################################################################################################# 104// #################################################################################################
@@ -107,12 +107,12 @@ static void get_deep_lookup(lua_State* L)
107* Return the registered factory for 'index' (deep userdata proxy), 107* Return the registered factory for 'index' (deep userdata proxy),
108* or nullptr if 'index' is not a deep userdata proxy. 108* or nullptr if 'index' is not a deep userdata proxy.
109*/ 109*/
110[[nodiscard]] static inline DeepFactory* get_factory(lua_State* L, int index, LookupMode mode_) 110[[nodiscard]] static inline DeepFactory* get_factory(lua_State* L_, int index, LookupMode mode_)
111{ 111{
112 // when looking inside a keeper, we are 100% sure the object is a deep userdata 112 // when looking inside a keeper, we are 100% sure the object is a deep userdata
113 if (mode_ == LookupMode::FromKeeper) 113 if (mode_ == LookupMode::FromKeeper)
114 { 114 {
115 DeepPrelude* const proxy{ *lua_tofulluserdata<DeepPrelude*>(L, index) }; 115 DeepPrelude* const proxy{ *lua_tofulluserdata<DeepPrelude*>(L_, index) };
116 // we can (and must) cast and fetch the internally stored factory 116 // we can (and must) cast and fetch the internally stored factory
117 return &proxy->m_factory; 117 return &proxy->m_factory;
118 } 118 }
@@ -121,31 +121,31 @@ static void get_deep_lookup(lua_State* L)
121 // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/factory database 121 // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/factory database
122 // it is the only way to ensure that the userdata is indeed a deep userdata! 122 // it is the only way to ensure that the userdata is indeed a deep userdata!
123 // of course, we could just trust the caller, but we won't 123 // of course, we could just trust the caller, but we won't
124 STACK_GROW( L, 1); 124 STACK_GROW( L_, 1);
125 STACK_CHECK_START_REL(L, 0); 125 STACK_CHECK_START_REL(L_, 0);
126 126
127 if (!lua_getmetatable( L, index)) // deep ... metatable? 127 if (!lua_getmetatable( L_, index)) // deep ... metatable?
128 { 128 {
129 return nullptr; // no metatable: can't be a deep userdata object! 129 return nullptr; // no metatable: can't be a deep userdata object!
130 } 130 }
131 131
132 // replace metatable with the factory pointer, if it is actually a deep userdata 132 // replace metatable with the factory pointer, if it is actually a deep userdata
133 get_deep_lookup( L); // deep ... factory|nil 133 get_deep_lookup( L_); // deep ... factory|nil
134 134
135 DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L, -1) }; // nullptr if not a userdata 135 DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata
136 lua_pop( L, 1); 136 lua_pop( L_, 1);
137 STACK_CHECK( L, 0); 137 STACK_CHECK( L_, 0);
138 return ret; 138 return ret;
139 } 139 }
140} 140}
141 141
142// ################################################################################################# 142// #################################################################################################
143 143
144void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_) 144void DeepFactory::DeleteDeepObject(lua_State* L_, DeepPrelude* o_)
145{ 145{
146 STACK_CHECK_START_REL(L, 0); 146 STACK_CHECK_START_REL(L_, 0);
147 o_->m_factory.deleteDeepObjectInternal(L, o_); 147 o_->m_factory.deleteDeepObjectInternal(L_, o_);
148 STACK_CHECK(L, 0); 148 STACK_CHECK(L_, 0);
149} 149}
150 150
151// ################################################################################################# 151// #################################################################################################
@@ -156,9 +156,9 @@ void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_)
156 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0. 156 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0.
157 * 157 *
158 */ 158 */
159[[nodiscard]] static int deep_userdata_gc(lua_State* L) 159[[nodiscard]] static int deep_userdata_gc(lua_State* L_)
160{ 160{
161 DeepPrelude* const* const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) }; 161 DeepPrelude* const* const proxy{ lua_tofulluserdata<DeepPrelude*>(L_, 1) };
162 DeepPrelude* const p{ *proxy }; 162 DeepPrelude* const p{ *proxy };
163 163
164 // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded 164 // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded
@@ -168,14 +168,14 @@ void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_)
168 if (isLastRef) 168 if (isLastRef)
169 { 169 {
170 // retrieve wrapped __gc 170 // retrieve wrapped __gc
171 lua_pushvalue( L, lua_upvalueindex( 1)); // self __gc? 171 lua_pushvalue( L_, lua_upvalueindex( 1)); // self __gc?
172 if (!lua_isnil( L, -1)) 172 if (!lua_isnil( L_, -1))
173 { 173 {
174 lua_insert( L, -2); // __gc self 174 lua_insert( L_, -2); // __gc self
175 lua_call( L, 1, 0); // 175 lua_call( L_, 1, 0); //
176 } 176 }
177 // we don't really know what remains on the stack at that point (depending on us finding a __gc or not), but we don't care 177 // we don't really know what remains on the stack at that point (depending on us finding a __gc or not), but we don't care
178 DeepFactory::DeleteDeepObject(L, p); 178 DeepFactory::DeleteDeepObject(L_, p);
179 } 179 }
180 return 0; 180 return 0;
181} 181}
@@ -388,17 +388,17 @@ int DeepFactory::pushDeepUserdata(DestState L, int nuv_) const
388* Reference count is not changed, and access to the deep userdata is not 388* Reference count is not changed, and access to the deep userdata is not
389* serialized. It is the module's responsibility to prevent conflicting usage. 389* serialized. It is the module's responsibility to prevent conflicting usage.
390*/ 390*/
391DeepPrelude* DeepFactory::toDeep(lua_State* L, int index) const 391DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index) const
392{ 392{
393 STACK_CHECK_START_REL(L, 0); 393 STACK_CHECK_START_REL(L_, 0);
394 // ensure it is actually a deep userdata we created 394 // ensure it is actually a deep userdata we created
395 if (get_factory(L, index, LookupMode::LaneBody) != this) 395 if (get_factory(L_, index, LookupMode::LaneBody) != this)
396 { 396 {
397 return nullptr; // no metatable, or wrong kind 397 return nullptr; // no metatable, or wrong kind
398 } 398 }
399 STACK_CHECK(L, 0); 399 STACK_CHECK(L_, 0);
400 400
401 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, index) }; 401 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L_, index) };
402 return *proxy; 402 return *proxy;
403} 403}
404 404
diff --git a/src/keeper.cpp b/src/keeper.cpp
index 51f6388..33da736 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -67,9 +67,9 @@ class keeper_fifo
67 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception 67 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
68 static void operator delete([[maybe_unused]] void* p_, KeeperState L_) { LUA_ASSERT(L_, !"should never be called"); } 68 static void operator delete([[maybe_unused]] void* p_, KeeperState L_) { LUA_ASSERT(L_, !"should never be called"); }
69 69
70 [[nodiscard]] static keeper_fifo* getPtr(lua_State* L, int idx_) 70 [[nodiscard]] static keeper_fifo* getPtr(lua_State* L_, int idx_)
71 { 71 {
72 return lua_tofulluserdata<keeper_fifo>(L, idx_); 72 return lua_tofulluserdata<keeper_fifo>(L_, idx_);
73 } 73 }
74}; 74};
75 75
@@ -78,16 +78,16 @@ static constexpr int kContentsTableIndex{ 1 };
78// ################################################################################################# 78// #################################################################################################
79 79
80// replaces the fifo ud by its uservalue on the stack 80// replaces the fifo ud by its uservalue on the stack
81[[nodiscard]] static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) 81[[nodiscard]] static keeper_fifo* prepare_fifo_access(lua_State* L_, int idx_)
82{ 82{
83 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, idx_) }; 83 keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, idx_) };
84 if (fifo != nullptr) 84 if (fifo != nullptr)
85 { 85 {
86 idx_ = lua_absindex(L, idx_); 86 idx_ = lua_absindex(L_, idx_);
87 STACK_GROW(L, 1); 87 STACK_GROW(L_, 1);
88 // we can replace the fifo userdata in the stack without fear of it being GCed, there are other references around 88 // we can replace the fifo userdata in the stack without fear of it being GCed, there are other references around
89 lua_getiuservalue(L, idx_, kContentsTableIndex); 89 lua_getiuservalue(L_, idx_, kContentsTableIndex);
90 lua_replace(L, idx_); 90 lua_replace(L_, idx_);
91 } 91 }
92 return fifo; 92 return fifo;
93} 93}
@@ -96,15 +96,15 @@ static constexpr int kContentsTableIndex{ 1 };
96 96
97// in: nothing 97// in: nothing
98// out: { first = 1, count = 0, limit = -1} 98// out: { first = 1, count = 0, limit = -1}
99[[nodiscard]] static keeper_fifo* fifo_new(KeeperState L) 99[[nodiscard]] static keeper_fifo* fifo_new(KeeperState L_)
100{ 100{
101 STACK_GROW(L, 2); 101 STACK_GROW(L_, 2);
102 STACK_CHECK_START_REL(L, 0); 102 STACK_CHECK_START_REL(L_, 0);
103 keeper_fifo* const fifo{ new (L) keeper_fifo{} }; 103 keeper_fifo* const fifo{ new (L_) keeper_fifo{} };
104 STACK_CHECK(L, 1); 104 STACK_CHECK(L_, 1);
105 lua_newtable(L); 105 lua_newtable(L_);
106 lua_setiuservalue(L, -2, kContentsTableIndex); 106 lua_setiuservalue(L_, -2, kContentsTableIndex);
107 STACK_CHECK(L, 1); 107 STACK_CHECK(L_, 1);
108 return fifo; 108 return fifo;
109} 109}
110 110
@@ -112,15 +112,15 @@ static constexpr int kContentsTableIndex{ 1 };
112 112
113// in: expect fifo ... on top of the stack 113// in: expect fifo ... on top of the stack
114// out: nothing, removes all pushed values from the stack 114// out: nothing, removes all pushed values from the stack
115static void fifo_push(lua_State* L, keeper_fifo* fifo_, int count_) 115static void fifo_push(lua_State* L_, keeper_fifo* fifo_, int count_)
116{ 116{
117 int const idx{ lua_gettop(L) - count_ }; 117 int const idx{ lua_gettop(L_) - count_ };
118 int const start{ fifo_->first + fifo_->count - 1 }; 118 int const start{ fifo_->first + fifo_->count - 1 };
119 // pop all additional arguments, storing them in the fifo 119 // pop all additional arguments, storing them in the fifo
120 for (int i = count_; i >= 1; --i) 120 for (int i = count_; i >= 1; --i)
121 { 121 {
122 // store in the fifo the value at the top of the stack at the specified index, popping it from the stack 122 // store in the fifo the value at the top of the stack at the specified index, popping it from the stack
123 lua_rawseti(L, idx, start + i); 123 lua_rawseti(L_, idx, start + i);
124 } 124 }
125 fifo_->count += count_; 125 fifo_->count += count_;
126} 126}
@@ -132,12 +132,12 @@ static void fifo_push(lua_State* L, keeper_fifo* fifo_, int count_)
132// expects exactly 1 value on the stack! 132// expects exactly 1 value on the stack!
133// currently only called with a count of 1, but this may change in the future 133// currently only called with a count of 1, but this may change in the future
134// function assumes that there is enough data in the fifo to satisfy the request 134// function assumes that there is enough data in the fifo to satisfy the request
135static void fifo_peek(lua_State* L, keeper_fifo* fifo_, int count_) 135static void fifo_peek(lua_State* L_, keeper_fifo* fifo_, int count_)
136{ 136{
137 STACK_GROW(L, count_); 137 STACK_GROW(L_, count_);
138 for (int i = 0; i < count_; ++i) 138 for (int i = 0; i < count_; ++i)
139 { 139 {
140 lua_rawgeti(L, 1, (fifo_->first + i)); 140 lua_rawgeti(L_, 1, (fifo_->first + i));
141 } 141 }
142} 142}
143 143
@@ -145,29 +145,29 @@ static void fifo_peek(lua_State* L, keeper_fifo* fifo_, int count_)
145 145
146// in: fifo 146// in: fifo
147// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number) 147// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number)
148static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) 148static void fifo_pop( lua_State* L_, keeper_fifo* fifo_, int count_)
149{ 149{
150 LUA_ASSERT(L, lua_istable(L, -1)); 150 LUA_ASSERT(L_, lua_istable(L_, -1));
151 int const fifo_idx{ lua_gettop(L) }; // ... fifotbl 151 int const fifo_idx{ lua_gettop(L_) }; // ... fifotbl
152 // each iteration pushes a value on the stack! 152 // each iteration pushes a value on the stack!
153 STACK_GROW(L, count_ + 2); 153 STACK_GROW(L_, count_ + 2);
154 // skip first item, we will push it last 154 // skip first item, we will push it last
155 for (int i = 1; i < count_; ++i) 155 for (int i = 1; i < count_; ++i)
156 { 156 {
157 int const at{ fifo_->first + i }; 157 int const at{ fifo_->first + i };
158 // push item on the stack 158 // push item on the stack
159 lua_rawgeti(L, fifo_idx, at); // ... fifotbl val 159 lua_rawgeti(L_, fifo_idx, at); // ... fifotbl val
160 // remove item from the fifo 160 // remove item from the fifo
161 lua_pushnil(L); // ... fifotbl val nil 161 lua_pushnil(L_); // ... fifotbl val nil
162 lua_rawseti(L, fifo_idx, at); // ... fifotbl val 162 lua_rawseti(L_, fifo_idx, at); // ... fifotbl val
163 } 163 }
164 // now process first item 164 // now process first item
165 { 165 {
166 int const at{ fifo_->first }; 166 int const at{ fifo_->first };
167 lua_rawgeti(L, fifo_idx, at); // ... fifotbl vals val 167 lua_rawgeti(L_, fifo_idx, at); // ... fifotbl vals val
168 lua_pushnil(L); // ... fifotbl vals val nil 168 lua_pushnil(L_); // ... fifotbl vals val nil
169 lua_rawseti(L, fifo_idx, at); // ... fifotbl vals val 169 lua_rawseti(L_, fifo_idx, at); // ... fifotbl vals val
170 lua_replace(L, fifo_idx); // ... vals 170 lua_replace(L_, fifo_idx); // ... vals
171 } 171 }
172 172
173 // avoid ever-growing indexes by resetting each time we detect the fifo is empty 173 // avoid ever-growing indexes by resetting each time we detect the fifo is empty
@@ -184,26 +184,26 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_)
184// out: fifos[ud] 184// out: fifos[ud]
185// xxh64 of string "kFifosRegKey" generated at https://www.pelock.com/products/hash-calculator 185// xxh64 of string "kFifosRegKey" generated at https://www.pelock.com/products/hash-calculator
186static constexpr RegistryUniqueKey kFifosRegKey{ 0x37F11CE5A6D191AAull }; 186static constexpr RegistryUniqueKey kFifosRegKey{ 0x37F11CE5A6D191AAull };
187static void push_table(lua_State* L, int idx_) 187static void push_table(lua_State* L_, int idx_)
188{ 188{
189 STACK_GROW(L, 5); 189 STACK_GROW(L_, 5);
190 STACK_CHECK_START_REL(L, 0); 190 STACK_CHECK_START_REL(L_, 0);
191 idx_ = lua_absindex(L, idx_); 191 idx_ = lua_absindex(L_, idx_);
192 kFifosRegKey.pushValue(L); // ud fifos 192 kFifosRegKey.pushValue(L_); // ud fifos
193 lua_pushvalue(L, idx_); // ud fifos ud 193 lua_pushvalue(L_, idx_); // ud fifos ud
194 lua_rawget(L, -2); // ud fifos fifos[ud] 194 lua_rawget(L_, -2); // ud fifos fifos[ud]
195 STACK_CHECK(L, 2); 195 STACK_CHECK(L_, 2);
196 if (lua_isnil(L, -1)) 196 if (lua_isnil(L_, -1))
197 { 197 {
198 lua_pop(L, 1); // ud fifos 198 lua_pop(L_, 1); // ud fifos
199 // add a new fifos table for this linda 199 // add a new fifos table for this linda
200 lua_newtable(L); // ud fifos fifos[ud] 200 lua_newtable(L_); // ud fifos fifos[ud]
201 lua_pushvalue(L, idx_); // ud fifos fifos[ud] ud 201 lua_pushvalue(L_, idx_); // ud fifos fifos[ud] ud
202 lua_pushvalue(L, -2); // ud fifos fifos[ud] ud fifos[ud] 202 lua_pushvalue(L_, -2); // ud fifos fifos[ud] ud fifos[ud]
203 lua_rawset(L, -4); // ud fifos fifos[ud] 203 lua_rawset(L_, -4); // ud fifos fifos[ud]
204 } 204 }
205 lua_remove(L, -2); // ud fifos[ud] 205 lua_remove(L_, -2); // ud fifos[ud]
206 STACK_CHECK(L, 1); 206 STACK_CHECK(L_, 1);
207} 207}
208 208
209// ################################################################################################# 209// #################################################################################################
@@ -263,16 +263,16 @@ int keeper_push_linda_storage(Linda& linda_, DestState L)
263// ################################################################################################# 263// #################################################################################################
264 264
265// in: linda_ud 265// in: linda_ud
266int keepercall_clear(lua_State* L) 266int keepercall_clear(lua_State* L_)
267{ 267{
268 STACK_GROW(L, 3); 268 STACK_GROW(L_, 3);
269 STACK_CHECK_START_REL(L, 0); 269 STACK_CHECK_START_REL(L_, 0);
270 kFifosRegKey.pushValue(L); // ud fifos 270 kFifosRegKey.pushValue(L_); // ud fifos
271 lua_pushvalue(L, 1); // ud fifos ud 271 lua_pushvalue(L_, 1); // ud fifos ud
272 lua_pushnil(L); // ud fifos ud nil 272 lua_pushnil(L_); // ud fifos ud nil
273 lua_rawset(L, -3); // ud fifos 273 lua_rawset(L_, -3); // ud fifos
274 lua_pop(L, 1); // ud 274 lua_pop(L_, 1); // ud
275 STACK_CHECK(L, 0); 275 STACK_CHECK(L_, 0);
276 return 0; 276 return 0;
277} 277}
278 278
@@ -280,35 +280,35 @@ int keepercall_clear(lua_State* L)
280 280
281// in: linda_ud, key, ... 281// in: linda_ud, key, ...
282// out: true|false 282// out: true|false
283int keepercall_send(lua_State* L) 283int keepercall_send(lua_State* L_)
284{ 284{
285 int const n{ lua_gettop(L) - 2 }; 285 int const n{ lua_gettop(L_) - 2 };
286 push_table(L, 1); // ud key ... fifos 286 push_table(L_, 1); // ud key ... fifos
287 // get the fifo associated to this key in this linda, create it if it doesn't exist 287 // get the fifo associated to this key in this linda, create it if it doesn't exist
288 lua_pushvalue(L, 2); // ud key ... fifos key 288 lua_pushvalue(L_, 2); // ud key ... fifos key
289 lua_rawget(L, -2); // ud key ... fifos fifo 289 lua_rawget(L_, -2); // ud key ... fifos fifo
290 if (lua_isnil(L, -1)) 290 if (lua_isnil(L_, -1))
291 { 291 {
292 lua_pop(L, 1); // ud key ... fifos 292 lua_pop(L_, 1); // ud key ... fifos
293 std::ignore = fifo_new(KeeperState{ L }); // ud key ... fifos fifo 293 std::ignore = fifo_new(KeeperState{ L_ }); // ud key ... fifos fifo
294 lua_pushvalue(L, 2); // ud key ... fifos fifo key 294 lua_pushvalue(L_, 2); // ud key ... fifos fifo key
295 lua_pushvalue(L, -2); // ud key ... fifos fifo key fifo 295 lua_pushvalue(L_, -2); // ud key ... fifos fifo key fifo
296 lua_rawset(L, -4); // ud key ... fifos fifo 296 lua_rawset(L_, -4); // ud key ... fifos fifo
297 } 297 }
298 lua_remove(L, -2); // ud key ... fifo 298 lua_remove(L_, -2); // ud key ... fifo
299 keeper_fifo* fifo{ keeper_fifo::getPtr(L, -1) }; 299 keeper_fifo* fifo{ keeper_fifo::getPtr(L_, -1) };
300 if (fifo->limit >= 0 && fifo->count + n > fifo->limit) 300 if (fifo->limit >= 0 && fifo->count + n > fifo->limit)
301 { 301 {
302 lua_settop(L, 0); // 302 lua_settop(L_, 0); //
303 lua_pushboolean(L, 0); // false 303 lua_pushboolean(L_, 0); // false
304 } 304 }
305 else 305 else
306 { 306 {
307 fifo = prepare_fifo_access(L, -1); // ud fifotbl 307 fifo = prepare_fifo_access(L_, -1); // ud fifotbl
308 lua_replace(L, 2); // ud fifotbl ... 308 lua_replace(L_, 2); // ud fifotbl ...
309 fifo_push(L, fifo, n); // ud fifotbl 309 fifo_push(L_, fifo, n); // ud fifotbl
310 lua_settop(L, 0); // 310 lua_settop(L_, 0); //
311 lua_pushboolean(L, 1); // true 311 lua_pushboolean(L_, 1); // true
312 } 312 }
313 return 1; 313 return 1;
314} 314}
@@ -317,33 +317,33 @@ int keepercall_send(lua_State* L)
317 317
318// in: linda_ud, key [, key]? 318// in: linda_ud, key [, key]?
319// out: (key, val) or nothing 319// out: (key, val) or nothing
320int keepercall_receive(lua_State* L) 320int keepercall_receive(lua_State* L_)
321{ 321{
322 int const top{ lua_gettop(L) }; 322 int const top{ lua_gettop(L_) };
323 push_table(L, 1); // ud keys fifos 323 push_table(L_, 1); // ud keys fifos
324 lua_replace(L, 1); // fifos keys 324 lua_replace(L_, 1); // fifos keys
325 for (int i = 2; i <= top; ++i) 325 for (int i = 2; i <= top; ++i)
326 { 326 {
327 lua_pushvalue(L, i); // fifos keys key[i] 327 lua_pushvalue(L_, i); // fifos keys key[i]
328 lua_rawget(L, 1); // fifos keys fifo 328 lua_rawget(L_, 1); // fifos keys fifo
329 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos keys fifotbl 329 keeper_fifo* const fifo{ prepare_fifo_access(L_, -1) }; // fifos keys fifotbl
330 if (fifo != nullptr && fifo->count > 0) 330 if (fifo != nullptr && fifo->count > 0)
331 { 331 {
332 fifo_pop(L, fifo, 1); // fifos keys val 332 fifo_pop(L_, fifo, 1); // fifos keys val
333 if (!lua_isnil(L, -1)) 333 if (!lua_isnil(L_, -1))
334 { 334 {
335 lua_replace(L, 1); // val keys 335 lua_replace(L_, 1); // val keys
336 lua_settop(L, i); // val keys key[i] 336 lua_settop(L_, i); // val keys key[i]
337 if (i != 2) 337 if (i != 2)
338 { 338 {
339 lua_replace(L, 2); // val key keys 339 lua_replace(L_, 2); // val key keys
340 lua_settop(L, 2); // val key 340 lua_settop(L_, 2); // val key
341 } 341 }
342 lua_insert(L, 1); // key, val 342 lua_insert(L_, 1); // key, val
343 return 2; 343 return 2;
344 } 344 }
345 } 345 }
346 lua_settop(L, top); // data keys 346 lua_settop(L_, top); // data keys
347 } 347 }
348 // nothing to receive 348 // nothing to receive
349 return 0; 349 return 0;
@@ -352,29 +352,29 @@ int keepercall_receive(lua_State* L)
352// ################################################################################################# 352// #################################################################################################
353 353
354// in: linda_ud key mincount [maxcount] 354// in: linda_ud key mincount [maxcount]
355int keepercall_receive_batched(lua_State* L) 355int keepercall_receive_batched(lua_State* L_)
356{ 356{
357 int const min_count{ static_cast<int>(lua_tointeger(L, 3)) }; 357 int const min_count{ static_cast<int>(lua_tointeger(L_, 3)) };
358 if (min_count > 0) 358 if (min_count > 0)
359 { 359 {
360 int const max_count{ static_cast<int>(luaL_optinteger(L, 4, min_count)) }; 360 int const max_count{ static_cast<int>(luaL_optinteger(L_, 4, min_count)) };
361 lua_settop(L, 2); // ud key 361 lua_settop(L_, 2); // ud key
362 lua_insert(L, 1); // key ud 362 lua_insert(L_, 1); // key ud
363 push_table(L, 2); // key ud fifos 363 push_table(L_, 2); // key ud fifos
364 lua_remove(L, 2); // key fifos 364 lua_remove(L_, 2); // key fifos
365 lua_pushvalue(L, 1); // key fifos key 365 lua_pushvalue(L_, 1); // key fifos key
366 lua_rawget(L, 2); // key fifos fifo 366 lua_rawget(L_, 2); // key fifos fifo
367 lua_remove(L, 2); // key fifo 367 lua_remove(L_, 2); // key fifo
368 keeper_fifo* const fifo{ prepare_fifo_access(L, 2) }; // key fifotbl 368 keeper_fifo* const fifo{ prepare_fifo_access(L_, 2) }; // key fifotbl
369 if (fifo != nullptr && fifo->count >= min_count) 369 if (fifo != nullptr && fifo->count >= min_count)
370 { 370 {
371 fifo_pop(L, fifo, std::min( max_count, fifo->count)); // key ... 371 fifo_pop(L_, fifo, std::min( max_count, fifo->count)); // key ...
372 } 372 }
373 else 373 else
374 { 374 {
375 lua_settop(L, 0); // 375 lua_settop(L_, 0); //
376 } 376 }
377 return lua_gettop(L); 377 return lua_gettop(L_);
378 } 378 }
379 else 379 else
380 { 380 {
@@ -386,23 +386,23 @@ int keepercall_receive_batched(lua_State* L)
386 386
387// in: linda_ud key n 387// in: linda_ud key n
388// out: true or nil 388// out: true or nil
389int keepercall_limit(lua_State* L) 389int keepercall_limit(lua_State* L_)
390{ 390{
391 int const limit{ static_cast<int>(lua_tointeger(L, 3)) }; 391 int const limit{ static_cast<int>(lua_tointeger(L_, 3)) };
392 push_table(L, 1); // ud key n fifos 392 push_table(L_, 1); // ud key n fifos
393 lua_replace(L, 1); // fifos key n 393 lua_replace(L_, 1); // fifos key n
394 lua_pop(L, 1); // fifos key 394 lua_pop(L_, 1); // fifos key
395 lua_pushvalue(L, -1); // fifos key key 395 lua_pushvalue(L_, -1); // fifos key key
396 lua_rawget(L, -3); // fifos key fifo|nil 396 lua_rawget(L_, -3); // fifos key fifo|nil
397 keeper_fifo* fifo{ keeper_fifo::getPtr(L, -1) }; 397 keeper_fifo* fifo{ keeper_fifo::getPtr(L_, -1) };
398 if (fifo == nullptr) 398 if (fifo == nullptr)
399 { // fifos key nil 399 { // fifos key nil
400 lua_pop(L, 1); // fifos key 400 lua_pop(L_, 1); // fifos key
401 fifo = fifo_new(KeeperState{ L }); // fifos key fifo 401 fifo = fifo_new(KeeperState{ L_ }); // fifos key fifo
402 lua_rawset(L, -3); // fifos 402 lua_rawset(L_, -3); // fifos
403 } 403 }
404 // remove any clutter on the stack 404 // remove any clutter on the stack
405 lua_settop(L, 0); 405 lua_settop(L_, 0);
406 // return true if we decide that blocked threads waiting to write on that key should be awakened 406 // return true if we decide that blocked threads waiting to write on that key should be awakened
407 // this is the case if we detect the key was full but it is no longer the case 407 // this is the case if we detect the key was full but it is no longer the case
408 if ( 408 if (
@@ -410,49 +410,49 @@ int keepercall_limit(lua_State* L)
410 && ((limit < 0) || (fifo->count < limit)) // the key is not full if unlimited or count is lower than the new limit 410 && ((limit < 0) || (fifo->count < limit)) // the key is not full if unlimited or count is lower than the new limit
411 ) 411 )
412 { 412 {
413 lua_pushboolean(L, 1); // true 413 lua_pushboolean(L_, 1); // true
414 } 414 }
415 // set the new limit 415 // set the new limit
416 fifo->limit = limit; 416 fifo->limit = limit;
417 // return 0 or 1 value 417 // return 0 or 1 value
418 return lua_gettop(L); 418 return lua_gettop(L_);
419} 419}
420 420
421// ################################################################################################# 421// #################################################################################################
422 422
423// in: linda_ud key [[val] ...] 423// in: linda_ud key [[val] ...]
424//out: true if the linda was full but it's no longer the case, else nothing 424//out: true if the linda was full but it's no longer the case, else nothing
425int keepercall_set(lua_State* L) 425int keepercall_set(lua_State* L_)
426{ 426{
427 bool should_wake_writers{ false }; 427 bool should_wake_writers{ false };
428 STACK_GROW(L, 6); 428 STACK_GROW(L_, 6);
429 429
430 // retrieve fifos associated with the linda 430 // retrieve fifos associated with the linda
431 push_table(L, 1); // ud key [val [, ...]] fifos 431 push_table(L_, 1); // ud key [val [, ...]] fifos
432 lua_replace(L, 1); // fifos key [val [, ...]] 432 lua_replace(L_, 1); // fifos key [val [, ...]]
433 433
434 // make sure we have a value on the stack 434 // make sure we have a value on the stack
435 if (lua_gettop(L) == 2) // fifos key 435 if (lua_gettop(L_) == 2) // fifos key
436 { 436 {
437 lua_pushvalue(L, -1); // fifos key key 437 lua_pushvalue(L_, -1); // fifos key key
438 lua_rawget(L, 1); // fifos key fifo|nil 438 lua_rawget(L_, 1); // fifos key fifo|nil
439 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! 439 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
440 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; 440 keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) };
441 if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil 441 if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil
442 { // fifos key fifo 442 { // fifos key fifo
443 if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it 443 if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it
444 { 444 {
445 lua_pop(L, 1); // fifos key 445 lua_pop(L_, 1); // fifos key
446 lua_pushnil(L); // fifos key nil 446 lua_pushnil(L_); // fifos key nil
447 lua_rawset(L, -3); // fifos 447 lua_rawset(L_, -3); // fifos
448 } 448 }
449 else 449 else
450 { 450 {
451 // we create room if the fifo was full but it is no longer the case 451 // we create room if the fifo was full but it is no longer the case
452 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit); 452 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit);
453 lua_remove(L, -2); // fifos fifo 453 lua_remove(L_, -2); // fifos fifo
454 lua_newtable(L); // fifos fifo {} 454 lua_newtable(L_); // fifos fifo {}
455 lua_setiuservalue(L, -2, kContentsTableIndex); // fifos fifo 455 lua_setiuservalue(L_, -2, kContentsTableIndex); // fifos fifo
456 fifo->first = 1; 456 fifo->first = 1;
457 fifo->count = 0; 457 fifo->count = 0;
458 } 458 }
@@ -460,59 +460,59 @@ int keepercall_set(lua_State* L)
460 } 460 }
461 else // set/replace contents stored at the specified key? 461 else // set/replace contents stored at the specified key?
462 { 462 {
463 int const count{ lua_gettop(L) - 2 }; // number of items we want to store 463 int const count{ lua_gettop(L_) - 2 }; // number of items we want to store
464 lua_pushvalue(L, 2); // fifos key [val [, ...]] key 464 lua_pushvalue(L_, 2); // fifos key [val [, ...]] key
465 lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil 465 lua_rawget(L_, 1); // fifos key [val [, ...]] fifo|nil
466 keeper_fifo* fifo{ keeper_fifo::getPtr(L, -1) }; 466 keeper_fifo* fifo{ keeper_fifo::getPtr(L_, -1) };
467 if (fifo == nullptr) // can be nullptr if we store a value at a new key 467 if (fifo == nullptr) // can be nullptr if we store a value at a new key
468 { // fifos key [val [, ...]] nil 468 { // fifos key [val [, ...]] nil
469 // no need to wake writers in that case, because a writer can't wait on an inexistent key 469 // no need to wake writers in that case, because a writer can't wait on an inexistent key
470 lua_pop(L, 1); // fifos key [val [, ...]] 470 lua_pop(L_, 1); // fifos key [val [, ...]]
471 std::ignore = fifo_new(KeeperState{ L }); // fifos key [val [, ...]] fifo 471 std::ignore = fifo_new(KeeperState{ L_ }); // fifos key [val [, ...]] fifo
472 lua_pushvalue(L, 2); // fifos key [val [, ...]] fifo key 472 lua_pushvalue(L_, 2); // fifos key [val [, ...]] fifo key
473 lua_pushvalue(L, -2); // fifos key [val [, ...]] fifo key fifo 473 lua_pushvalue(L_, -2); // fifos key [val [, ...]] fifo key fifo
474 lua_rawset(L, 1); // fifos key [val [, ...]] fifo 474 lua_rawset(L_, 1); // fifos key [val [, ...]] fifo
475 } 475 }
476 else // the fifo exists, we just want to update its contents 476 else // the fifo exists, we just want to update its contents
477 { // fifos key [val [, ...]] fifo 477 { // fifos key [val [, ...]] fifo
478 // we create room if the fifo was full but it is no longer the case 478 // we create room if the fifo was full but it is no longer the case
479 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit) && (count < fifo->limit); 479 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit) && (count < fifo->limit);
480 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! 480 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
481 lua_newtable(L); // fifos key [val [, ...]] fifo {} 481 lua_newtable(L_); // fifos key [val [, ...]] fifo {}
482 lua_setiuservalue(L, -2, kContentsTableIndex); // fifos key [val [, ...]] fifo 482 lua_setiuservalue(L_, -2, kContentsTableIndex); // fifos key [val [, ...]] fifo
483 fifo->first = 1; 483 fifo->first = 1;
484 fifo->count = 0; 484 fifo->count = 0;
485 } 485 }
486 fifo = prepare_fifo_access(L, -1); // fifos key [val [, ...]] fifotbl 486 fifo = prepare_fifo_access(L_, -1); // fifos key [val [, ...]] fifotbl
487 // move the fifo below the values we want to store 487 // move the fifo below the values we want to store
488 lua_insert(L, 3); // fifos key fifotbl [val [, ...]] 488 lua_insert(L_, 3); // fifos key fifotbl [val [, ...]]
489 fifo_push(L, fifo, count); // fifos key fifotbl 489 fifo_push(L_, fifo, count); // fifos key fifotbl
490 } 490 }
491 return should_wake_writers ? (lua_pushboolean(L, 1), 1) : 0; 491 return should_wake_writers ? (lua_pushboolean(L_, 1), 1) : 0;
492} 492}
493 493
494// ################################################################################################# 494// #################################################################################################
495 495
496// in: linda_ud key [count] 496// in: linda_ud key [count]
497// out: at most <count> values 497// out: at most <count> values
498int keepercall_get(lua_State* L) 498int keepercall_get(lua_State* L_)
499{ 499{
500 int count{ 1 }; 500 int count{ 1 };
501 if (lua_gettop(L) == 3) // ud key count 501 if (lua_gettop(L_) == 3) // ud key count
502 { 502 {
503 count = static_cast<int>(lua_tointeger(L, 3)); 503 count = static_cast<int>(lua_tointeger(L_, 3));
504 lua_pop(L, 1); // ud key 504 lua_pop(L_, 1); // ud key
505 } 505 }
506 push_table(L, 1); // ud key fifos 506 push_table(L_, 1); // ud key fifos
507 lua_replace(L, 1); // fifos key 507 lua_replace(L_, 1); // fifos key
508 lua_rawget(L, 1); // fifos fifo 508 lua_rawget(L_, 1); // fifos fifo
509 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos fifotbl 509 keeper_fifo* const fifo{ prepare_fifo_access(L_, -1) }; // fifos fifotbl
510 if (fifo != nullptr && fifo->count > 0) 510 if (fifo != nullptr && fifo->count > 0)
511 { 511 {
512 lua_remove(L, 1); // fifotbl 512 lua_remove(L_, 1); // fifotbl
513 count = std::min(count, fifo->count); 513 count = std::min(count, fifo->count);
514 // read <count> value off the fifo 514 // read <count> value off the fifo
515 fifo_peek(L, fifo, count); // fifotbl ... 515 fifo_peek(L_, fifo, count); // fifotbl ...
516 return count; 516 return count;
517 } 517 }
518 // no fifo was ever registered for this key, or it is empty 518 // no fifo was ever registered for this key, or it is empty
@@ -522,69 +522,69 @@ int keepercall_get(lua_State* L)
522// ################################################################################################# 522// #################################################################################################
523 523
524// in: linda_ud [, key [, ...]] 524// in: linda_ud [, key [, ...]]
525int keepercall_count(lua_State* L) 525int keepercall_count(lua_State* L_)
526{ 526{
527 push_table(L, 1); // ud keys fifos 527 push_table(L_, 1); // ud keys fifos
528 switch (lua_gettop(L)) 528 switch (lua_gettop(L_))
529 { 529 {
530 // no key is specified: return a table giving the count of all known keys 530 // no key is specified: return a table giving the count of all known keys
531 case 2: // ud fifos 531 case 2: // ud fifos
532 lua_newtable(L); // ud fifos out 532 lua_newtable(L_); // ud fifos out
533 lua_replace(L, 1); // out fifos 533 lua_replace(L_, 1); // out fifos
534 lua_pushnil(L); // out fifos nil 534 lua_pushnil(L_); // out fifos nil
535 while (lua_next(L, 2)) // out fifos key fifo 535 while (lua_next(L_, 2)) // out fifos key fifo
536 { 536 {
537 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; 537 keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) };
538 lua_pop(L, 1); // out fifos key 538 lua_pop(L_, 1); // out fifos key
539 lua_pushvalue(L, -1); // out fifos key key 539 lua_pushvalue(L_, -1); // out fifos key key
540 lua_pushinteger(L, fifo->count); // out fifos key key count 540 lua_pushinteger(L_, fifo->count); // out fifos key key count
541 lua_rawset(L, -5); // out fifos key 541 lua_rawset(L_, -5); // out fifos key
542 } 542 }
543 lua_pop(L, 1); // out 543 lua_pop(L_, 1); // out
544 break; 544 break;
545 545
546 // 1 key is specified: return its count 546 // 1 key is specified: return its count
547 case 3: // ud key fifos 547 case 3: // ud key fifos
548 lua_replace(L, 1); // fifos key 548 lua_replace(L_, 1); // fifos key
549 lua_rawget(L, -2); // fifos fifo|nil 549 lua_rawget(L_, -2); // fifos fifo|nil
550 if (lua_isnil(L, -1)) // the key is unknown 550 if (lua_isnil(L_, -1)) // the key is unknown
551 { // fifos nil 551 { // fifos nil
552 lua_remove(L, -2); // nil 552 lua_remove(L_, -2); // nil
553 } 553 }
554 else // the key is known 554 else // the key is known
555 { // fifos fifo 555 { // fifos fifo
556 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; 556 keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) };
557 lua_pushinteger(L, fifo->count); // fifos fifo count 557 lua_pushinteger(L_, fifo->count); // fifos fifo count
558 lua_replace(L, -3); // count fifo 558 lua_replace(L_, -3); // count fifo
559 lua_pop(L, 1); // count 559 lua_pop(L_, 1); // count
560 } 560 }
561 break; 561 break;
562 562
563 // a variable number of keys is specified: return a table of their counts 563 // a variable number of keys is specified: return a table of their counts
564 default: // ud keys fifos 564 default: // ud keys fifos
565 lua_newtable(L); // ud keys... fifos out 565 lua_newtable(L_); // ud keys... fifos out
566 lua_replace(L, 1); // out keys... fifos 566 lua_replace(L_, 1); // out keys... fifos
567 // shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable 567 // shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable
568 lua_insert(L, 2); // out fifos keys... 568 lua_insert(L_, 2); // out fifos keys...
569 while (lua_gettop(L) > 2) 569 while (lua_gettop(L_) > 2)
570 { 570 {
571 lua_pushvalue(L, -1); // out fifos keys... key 571 lua_pushvalue(L_, -1); // out fifos keys... key
572 lua_rawget(L, 2); // out fifos keys... fifo|nil 572 lua_rawget(L_, 2); // out fifos keys... fifo|nil
573 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) }; 573 keeper_fifo* const fifo{ keeper_fifo::getPtr(L_, -1) };
574 lua_pop(L, 1); // out fifos keys... 574 lua_pop(L_, 1); // out fifos keys...
575 if (fifo != nullptr) // the key is known 575 if (fifo != nullptr) // the key is known
576 { 576 {
577 lua_pushinteger(L, fifo->count); // out fifos keys... count 577 lua_pushinteger(L_, fifo->count); // out fifos keys... count
578 lua_rawset(L, 1); // out fifos keys... 578 lua_rawset(L_, 1); // out fifos keys...
579 } 579 }
580 else // the key is unknown 580 else // the key is unknown
581 { 581 {
582 lua_pop(L, 1); // out fifos keys... 582 lua_pop(L_, 1); // out fifos keys...
583 } 583 }
584 } // all keys are exhausted // out fifos 584 } // all keys are exhausted // out fifos
585 lua_pop(L, 1); // out 585 lua_pop(L_, 1); // out
586 } 586 }
587 LUA_ASSERT(L, lua_gettop(L) == 1); 587 LUA_ASSERT(L_, lua_gettop(L_) == 1);
588 return 1; 588 return 1;
589} 589}
590 590
@@ -651,23 +651,23 @@ void close_keepers(Universe* U)
651 * function never fails. 651 * function never fails.
652 * settings table is expected at position 1 on the stack 652 * settings table is expected at position 1 on the stack
653 */ 653 */
654void init_keepers(Universe* U, lua_State* L) 654void init_keepers(Universe* U, lua_State* L_)
655{ 655{
656 LUA_ASSERT(L, lua_gettop(L) == 1 && lua_istable(L, 1)); 656 LUA_ASSERT(L_, lua_gettop(L_) == 1 && lua_istable(L_, 1));
657 STACK_CHECK_START_REL(L, 0); // L K 657 STACK_CHECK_START_REL(L_, 0); // L_ K
658 lua_getfield(L, 1, "nb_keepers"); // settings nb_keepers 658 lua_getfield(L_, 1, "nb_keepers"); // settings nb_keepers
659 int const nb_keepers{ static_cast<int>(lua_tointeger(L, -1)) }; 659 int const nb_keepers{ static_cast<int>(lua_tointeger(L_, -1)) };
660 lua_pop(L, 1); // settings 660 lua_pop(L_, 1); // settings
661 if (nb_keepers < 1) 661 if (nb_keepers < 1)
662 { 662 {
663 raise_luaL_error(L, "Bad number of keepers (%d)", nb_keepers); 663 raise_luaL_error(L_, "Bad number of keepers (%d)", nb_keepers);
664 } 664 }
665 STACK_CHECK(L, 0); 665 STACK_CHECK(L_, 0);
666 666
667 lua_getfield(L, 1, "keepers_gc_threshold"); // settings keepers_gc_threshold 667 lua_getfield(L_, 1, "keepers_gc_threshold"); // settings keepers_gc_threshold
668 int const keepers_gc_threshold{ static_cast<int>(lua_tointeger(L, -1)) }; 668 int const keepers_gc_threshold{ static_cast<int>(lua_tointeger(L_, -1)) };
669 lua_pop(L, 1); // settings 669 lua_pop(L_, 1); // settings
670 STACK_CHECK(L, 0); 670 STACK_CHECK(L_, 0);
671 671
672 // Keepers contains an array of 1 Keeper, adjust for the actual number of keeper states 672 // Keepers contains an array of 1 Keeper, adjust for the actual number of keeper states
673 { 673 {
@@ -675,7 +675,7 @@ void init_keepers(Universe* U, lua_State* L)
675 U->keepers = static_cast<Keepers*>(U->internal_allocator.alloc(bytes)); 675 U->keepers = static_cast<Keepers*>(U->internal_allocator.alloc(bytes));
676 if (U->keepers == nullptr) 676 if (U->keepers == nullptr)
677 { 677 {
678 raise_luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); 678 raise_luaL_error(L_, "init_keepers() failed while creating keeper array; out of memory");
679 } 679 }
680 U->keepers->Keepers::Keepers(); 680 U->keepers->Keepers::Keepers();
681 U->keepers->gc_threshold = keepers_gc_threshold; 681 U->keepers->gc_threshold = keepers_gc_threshold;
@@ -689,10 +689,10 @@ void init_keepers(Universe* U, lua_State* L)
689 for (int i = 0; i < nb_keepers; ++i) // settings 689 for (int i = 0; i < nb_keepers; ++i) // settings
690 { 690 {
691 // note that we will leak K if we raise an error later 691 // note that we will leak K if we raise an error later
692 KeeperState const K{ create_state(U, L) }; 692 KeeperState const K{ create_state(U, L_) };
693 if (K == nullptr) 693 if (K == nullptr)
694 { 694 {
695 raise_luaL_error(L, "init_keepers() failed while creating keeper states; out of memory"); 695 raise_luaL_error(L_, "init_keepers() failed while creating keeper states; out of memory");
696 } 696 }
697 697
698 U->keepers->keeper_array[i].L = K; 698 U->keepers->keeper_array[i].L = K;
@@ -717,35 +717,35 @@ void init_keepers(Universe* U, lua_State* L)
717 STACK_CHECK(K, 0); 717 STACK_CHECK(K, 0);
718 718
719 // copy package.path and package.cpath from the source state (TODO: use _R._LOADED.package instead of _G.package) 719 // copy package.path and package.cpath from the source state (TODO: use _R._LOADED.package instead of _G.package)
720 lua_getglobal(L, "package"); // settings package 720 lua_getglobal(L_, "package"); // settings package
721 if (!lua_isnil(L, -1)) 721 if (!lua_isnil(L_, -1))
722 { 722 {
723 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately 723 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately
724 InterCopyContext c{ U, DestState{ K }, SourceState{ L }, {}, SourceIndex{ lua_absindex(L, -1) }, {}, LookupMode::ToKeeper, {} }; 724 InterCopyContext c{ U, DestState{ K }, SourceState{ L_ }, {}, SourceIndex{ lua_absindex(L_, -1) }, {}, LookupMode::ToKeeper, {} };
725 if (c.inter_copy_package() != InterCopyResult::Success) 725 if (c.inter_copy_package() != InterCopyResult::Success)
726 { 726 {
727 // if something went wrong, the error message is at the top of the stack 727 // if something went wrong, the error message is at the top of the stack
728 lua_remove(L, -2); // settings error_msg 728 lua_remove(L_, -2); // settings error_msg
729 raise_lua_error(L); 729 raise_lua_error(L_);
730 } 730 }
731 } 731 }
732 lua_pop(L, 1); // settings 732 lua_pop(L_, 1); // settings
733 STACK_CHECK(L, 0); 733 STACK_CHECK(L_, 0);
734 STACK_CHECK(K, 0); 734 STACK_CHECK(K, 0);
735 735
736 // attempt to call on_state_create(), if we have one and it is a C function 736 // attempt to call on_state_create(), if we have one and it is a C function
737 // (only support a C function because we can't transfer executable Lua code in keepers) 737 // (only support a C function because we can't transfer executable Lua code in keepers)
738 // will raise an error in L in case of problem 738 // will raise an error in L_ in case of problem
739 call_on_state_create(U, K, L, LookupMode::ToKeeper); 739 call_on_state_create(U, K, L_, LookupMode::ToKeeper);
740 740
741 // to see VM name in Decoda debugger 741 // to see VM name in Decoda debugger
742 lua_pushfstring(K, "Keeper #%d", i + 1); // "Keeper #n" 742 lua_pushfstring(K, "Keeper #%d", i + 1); // "Keeper #n"
743 lua_setglobal(K, "decoda_name"); // 743 lua_setglobal(K, "decoda_name"); //
744 // create the fifos table in the keeper state 744 // create the fifos table in the keeper state
745 kFifosRegKey.setValue(K, [](lua_State* L) { lua_newtable(L); }); 745 kFifosRegKey.setValue(K, [](lua_State* L_) { lua_newtable(L_); });
746 STACK_CHECK(K, 0); 746 STACK_CHECK(K, 0);
747 } 747 }
748 STACK_CHECK(L, 0); 748 STACK_CHECK(L_, 0);
749} 749}
750 750
751// ################################################################################################# 751// #################################################################################################
@@ -776,25 +776,25 @@ void Linda::releaseKeeper(Keeper* K_) const
776 776
777// ################################################################################################# 777// #################################################################################################
778 778
779void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_) 779void keeper_toggle_nil_sentinels(lua_State* L_, int val_i_, LookupMode const mode_)
780{ 780{
781 int const n{ lua_gettop(L) }; 781 int const n{ lua_gettop(L_) };
782 for (int i = val_i_; i <= n; ++i) 782 for (int i = val_i_; i <= n; ++i)
783 { 783 {
784 if (mode_ == LookupMode::ToKeeper) 784 if (mode_ == LookupMode::ToKeeper)
785 { 785 {
786 if (lua_isnil(L, i)) 786 if (lua_isnil(L_, i))
787 { 787 {
788 kNilSentinel.pushKey(L); 788 kNilSentinel.pushKey(L_);
789 lua_replace(L, i); 789 lua_replace(L_, i);
790 } 790 }
791 } 791 }
792 else 792 else
793 { 793 {
794 if (kNilSentinel.equals(L, i)) 794 if (kNilSentinel.equals(L_, i))
795 { 795 {
796 lua_pushnil(L); 796 lua_pushnil(L_);
797 lua_replace(L, i); 797 lua_replace(L_, i);
798 } 798 }
799 } 799 }
800 } 800 }
@@ -811,20 +811,20 @@ void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode
811* 811*
812* Returns: number of return values (pushed to 'L'), unset in case of error 812* Returns: number of return values (pushed to 'L'), unset in case of error
813*/ 813*/
814KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua_State* L, void* linda, int starting_index) 814KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua_State* L_, void* linda, int starting_index)
815{ 815{
816 KeeperCallResult result; 816 KeeperCallResult result;
817 int const args{ starting_index ? (lua_gettop(L) - starting_index + 1) : 0 }; 817 int const args{ starting_index ? (lua_gettop(L_) - starting_index + 1) : 0 };
818 int const top_K{ lua_gettop(K) }; 818 int const top_K{ lua_gettop(K) };
819 // if we didn't do anything wrong, the keeper stack should be clean 819 // if we didn't do anything wrong, the keeper stack should be clean
820 LUA_ASSERT(L, lua_gettop(K) == 0); 820 LUA_ASSERT(L_, lua_gettop(K) == 0);
821 821
822 STACK_GROW(K, 2); 822 STACK_GROW(K, 2);
823 PUSH_KEEPER_FUNC(K, func_); // func_ 823 PUSH_KEEPER_FUNC(K, func_); // func_
824 lua_pushlightuserdata(K, linda); // func_ linda 824 lua_pushlightuserdata(K, linda); // func_ linda
825 if ( 825 if (
826 (args == 0) || 826 (args == 0) ||
827 (InterCopyContext{ U, DestState{ K }, SourceState{ L }, {}, {}, {}, LookupMode::ToKeeper, {} }.inter_copy(args) == InterCopyResult::Success) 827 (InterCopyContext{ U, DestState{ K }, SourceState{ L_ }, {}, {}, {}, LookupMode::ToKeeper, {} }.inter_copy(args) == InterCopyResult::Success)
828 ) 828 )
829 { // func_ linda args... 829 { // func_ linda args...
830 lua_call(K, 1 + args, LUA_MULTRET); // result... 830 lua_call(K, 1 + args, LUA_MULTRET); // result...
@@ -835,8 +835,8 @@ KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua
835 // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) 835 // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread)
836 if ( 836 if (
837 (retvals == 0) || 837 (retvals == 0) ||
838 (InterCopyContext{ U, DestState{ L }, SourceState{ K }, {}, {}, {}, LookupMode::FromKeeper, {} }.inter_move(retvals) == InterCopyResult::Success) 838 (InterCopyContext{ U, DestState{ L_ }, SourceState{ K }, {}, {}, {}, LookupMode::FromKeeper, {} }.inter_move(retvals) == InterCopyResult::Success)
839 ) // K->L 839 ) // K->L_
840 { 840 {
841 result.emplace(retvals); 841 result.emplace(retvals);
842 } 842 }
@@ -862,7 +862,7 @@ KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua
862 int const gc_usage_after{ lua_gc(K, LUA_GCCOUNT, 0) }; 862 int const gc_usage_after{ lua_gc(K, LUA_GCCOUNT, 0) };
863 if (gc_usage_after > gc_threshold) [[unlikely]] 863 if (gc_usage_after > gc_threshold) [[unlikely]]
864 { 864 {
865 raise_luaL_error(L, "Keeper GC threshold is too low, need at least %d", gc_usage_after); 865 raise_luaL_error(L_, "Keeper GC threshold is too low, need at least %d", gc_usage_after);
866 } 866 }
867 } 867 }
868 } 868 }
diff --git a/src/keeper.h b/src/keeper.h
index 6688fe0..3740fc5 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -39,24 +39,24 @@ struct Keepers
39// xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator 39// xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator
40static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; 40static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" };
41 41
42void init_keepers(Universe* U, lua_State* L); 42void init_keepers(Universe* U, lua_State* L_);
43void close_keepers(Universe* U); 43void close_keepers(Universe* U);
44 44
45void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_); 45void keeper_toggle_nil_sentinels(lua_State* L_, int val_i_, LookupMode const mode_);
46[[nodiscard]] int keeper_push_linda_storage(Linda& linda_, DestState L); 46[[nodiscard]] int keeper_push_linda_storage(Linda& linda_, DestState L);
47 47
48using keeper_api_t = lua_CFunction; 48using keeper_api_t = lua_CFunction;
49#define KEEPER_API(_op) keepercall_##_op 49#define KEEPER_API(_op) keepercall_##_op
50#define PUSH_KEEPER_FUNC lua_pushcfunction 50#define PUSH_KEEPER_FUNC lua_pushcfunction
51// lua_Cfunctions to run inside a keeper state 51// lua_Cfunctions to run inside a keeper state
52[[nodiscard]] int keepercall_clear(lua_State* L); 52[[nodiscard]] int keepercall_clear(lua_State* L_);
53[[nodiscard]] int keepercall_send(lua_State* L); 53[[nodiscard]] int keepercall_send(lua_State* L_);
54[[nodiscard]] int keepercall_receive(lua_State* L); 54[[nodiscard]] int keepercall_receive(lua_State* L_);
55[[nodiscard]] int keepercall_receive_batched(lua_State* L); 55[[nodiscard]] int keepercall_receive_batched(lua_State* L_);
56[[nodiscard]] int keepercall_limit(lua_State* L); 56[[nodiscard]] int keepercall_limit(lua_State* L_);
57[[nodiscard]] int keepercall_get(lua_State* L); 57[[nodiscard]] int keepercall_get(lua_State* L_);
58[[nodiscard]] int keepercall_set(lua_State* L); 58[[nodiscard]] int keepercall_set(lua_State* L_);
59[[nodiscard]] int keepercall_count(lua_State* L); 59[[nodiscard]] int keepercall_count(lua_State* L_);
60 60
61using KeeperCallResult = Unique<std::optional<int>>; 61using KeeperCallResult = Unique<std::optional<int>>;
62[[nodiscard]] KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t _func, lua_State* L, void* linda, int starting_index); 62[[nodiscard]] KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t _func, lua_State* L_, void* linda, int starting_index);
diff --git a/src/lanes.cpp b/src/lanes.cpp
index e150eea..d87d93e 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -202,22 +202,22 @@ void Lane::startThread(int priority_)
202#define ERROR_FULL_STACK 1 // must be either 0 or 1 as we do some index arithmetics with it! 202#define ERROR_FULL_STACK 1 // must be either 0 or 1 as we do some index arithmetics with it!
203 203
204// intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed 204// intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed
205static void securize_debug_threadname(lua_State* L, Lane* lane_) 205static void securize_debug_threadname(lua_State* L_, Lane* lane_)
206{ 206{
207 STACK_CHECK_START_REL(L, 0); 207 STACK_CHECK_START_REL(L_, 0);
208 STACK_GROW(L, 3); 208 STACK_GROW(L_, 3);
209 lua_getiuservalue(L, 1, 1); 209 lua_getiuservalue(L_, 1, 1);
210 lua_newtable(L); 210 lua_newtable(L_);
211 // Lua 5.1 can't do 'lane_->debug_name = lua_pushstring(L, lane_->debug_name);' 211 // Lua 5.1 can't do 'lane_->debug_name = lua_pushstring(L, lane_->debug_name);'
212 lua_pushstring(L, lane_->debug_name); 212 lua_pushstring(L_, lane_->debug_name);
213 lane_->debug_name = lua_tostring(L, -1); 213 lane_->debug_name = lua_tostring(L_, -1);
214 lua_rawset(L, -3); 214 lua_rawset(L_, -3);
215 lua_pop(L, 1); 215 lua_pop(L_, 1);
216 STACK_CHECK(L, 0); 216 STACK_CHECK(L_, 0);
217} 217}
218 218
219#if ERROR_FULL_STACK 219#if ERROR_FULL_STACK
220[[nodiscard]] static int lane_error(lua_State* L); 220[[nodiscard]] static int lane_error(lua_State* L_);
221// xxh64 of string "kStackTraceRegKey" generated at https://www.pelock.com/products/hash-calculator 221// xxh64 of string "kStackTraceRegKey" generated at https://www.pelock.com/products/hash-calculator
222static constexpr RegistryUniqueKey kStackTraceRegKey{ 0x3F327747CACAA904ull }; 222static constexpr RegistryUniqueKey kStackTraceRegKey{ 0x3F327747CACAA904ull };
223#endif // ERROR_FULL_STACK 223#endif // ERROR_FULL_STACK
@@ -255,20 +255,20 @@ Lane::~Lane()
255 255
256// Push the finalizers table on the stack. 256// Push the finalizers table on the stack.
257// If there is no existing table, create ti. 257// If there is no existing table, create ti.
258static void push_finalizers_table(lua_State* L) 258static void push_finalizers_table(lua_State* L_)
259{ 259{
260 STACK_GROW(L, 3); 260 STACK_GROW(L_, 3);
261 STACK_CHECK_START_REL(L, 0); 261 STACK_CHECK_START_REL(L_, 0);
262 262
263 kFinalizerRegKey.pushValue(L); // ? 263 kFinalizerRegKey.pushValue(L_); // ?
264 if (lua_isnil(L, -1)) // nil? 264 if (lua_isnil(L_, -1)) // nil?
265 { 265 {
266 lua_pop(L, 1); // 266 lua_pop(L_, 1); //
267 // store a newly created table in the registry, but leave it on the stack too 267 // store a newly created table in the registry, but leave it on the stack too
268 lua_newtable(L); // t 268 lua_newtable(L_); // t
269 kFinalizerRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // t 269 kFinalizerRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // t
270 } 270 }
271 STACK_CHECK(L, 1); 271 STACK_CHECK(L_, 1);
272} 272}
273 273
274// ################################################################################################# 274// #################################################################################################
@@ -283,21 +283,21 @@ static void push_finalizers_table(lua_State* L)
283// 283//
284LUAG_FUNC(set_finalizer) 284LUAG_FUNC(set_finalizer)
285{ 285{
286 luaL_argcheck(L, lua_isfunction(L, 1), 1, "finalizer should be a function"); 286 luaL_argcheck(L_, lua_isfunction(L_, 1), 1, "finalizer should be a function");
287 luaL_argcheck(L, lua_gettop( L) == 1, 1, "too many arguments"); 287 luaL_argcheck(L_, lua_gettop(L_) == 1, 1, "too many arguments");
288 // Get the current finalizer table (if any), create one if it doesn't exist 288 // Get the current finalizer table (if any), create one if it doesn't exist
289 push_finalizers_table(L); // finalizer {finalisers} 289 push_finalizers_table(L_); // finalizer {finalisers}
290 STACK_GROW(L, 2); 290 STACK_GROW(L_, 2);
291 lua_pushinteger(L, lua_rawlen(L, -1) + 1); // finalizer {finalisers} idx 291 lua_pushinteger(L_, lua_rawlen(L_, -1) + 1); // finalizer {finalisers} idx
292 lua_pushvalue(L, 1); // finalizer {finalisers} idx finalizer 292 lua_pushvalue(L_, 1); // finalizer {finalisers} idx finalizer
293 lua_rawset(L, -3); // finalizer {finalisers} 293 lua_rawset(L_, -3); // finalizer {finalisers}
294 lua_pop(L, 2); // 294 lua_pop(L_, 2);
295 return 0; 295 return 0;
296} 296}
297 297
298// ################################################################################################# 298// #################################################################################################
299 299
300static void push_stack_trace(lua_State* L, int rc_, int stk_base_) 300static void push_stack_trace(lua_State* L_, int rc_, int stk_base_)
301{ 301{
302 // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry 302 // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry
303 switch(rc_) 303 switch(rc_)
@@ -308,16 +308,16 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
308 case LUA_ERRRUN: // cancellation or a runtime error 308 case LUA_ERRRUN: // cancellation or a runtime error
309#if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler 309#if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler
310 { 310 {
311 STACK_CHECK_START_REL(L, 0); 311 STACK_CHECK_START_REL(L_, 0);
312 // fetch the call stack table from the registry where the handler stored it 312 // fetch the call stack table from the registry where the handler stored it
313 STACK_GROW(L, 1); 313 STACK_GROW(L_, 1);
314 // yields nil if no stack was generated (in case of cancellation for example) 314 // yields nil if no stack was generated (in case of cancellation for example)
315 kStackTraceRegKey.pushValue(L); // err trace|nil 315 kStackTraceRegKey.pushValue(L_); // err trace|nil
316 STACK_CHECK(L, 1); 316 STACK_CHECK(L_, 1);
317 317
318 // For cancellation the error message is kCancelError, and a stack trace isn't placed 318 // For cancellation the error message is kCancelError, and a stack trace isn't placed
319 // For other errors, the message can be whatever was thrown, and we should have a stack trace table 319 // For other errors, the message can be whatever was thrown, and we should have a stack trace table
320 LUA_ASSERT(L, lua_type(L, 1 + stk_base_) == (kCancelError.equals(L, stk_base_) ? LUA_TNIL : LUA_TTABLE)); 320 LUA_ASSERT(L_, lua_type(L_, 1 + stk_base_) == (kCancelError.equals(L_, stk_base_) ? LUA_TNIL : LUA_TTABLE));
321 // Just leaving the stack trace table on the stack is enough to get it through to the master. 321 // Just leaving the stack trace table on the stack is enough to get it through to the master.
322 break; 322 break;
323 } 323 }
@@ -327,7 +327,7 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
327 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) 327 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition)
328 default: 328 default:
329 // we should have a single value which is either a string (the error message) or kCancelError 329 // we should have a single value which is either a string (the error message) or kCancelError
330 LUA_ASSERT(L, (lua_gettop(L) == stk_base_) && ((lua_type(L, stk_base_) == LUA_TSTRING) || kCancelError.equals(L, stk_base_))); 330 LUA_ASSERT(L_, (lua_gettop(L_) == stk_base_) && ((lua_type(L_, stk_base_) == LUA_TSTRING) || kCancelError.equals(L_, stk_base_)));
331 break; 331 break;
332 } 332 }
333} 333}
@@ -347,45 +347,45 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
347// TBD: should we add stack trace on failing finalizer, wouldn't be hard.. 347// TBD: should we add stack trace on failing finalizer, wouldn't be hard..
348// 348//
349 349
350[[nodiscard]] static int run_finalizers(lua_State* L, int lua_rc_) 350[[nodiscard]] static int run_finalizers(lua_State* L_, int lua_rc_)
351{ 351{
352 kFinalizerRegKey.pushValue(L); // ... finalizers? 352 kFinalizerRegKey.pushValue(L_); // ... finalizers?
353 if (lua_isnil(L, -1)) 353 if (lua_isnil(L_, -1))
354 { 354 {
355 lua_pop(L, 1); 355 lua_pop(L_, 1);
356 return 0; // no finalizers 356 return 0; // no finalizers
357 } 357 }
358 358
359 STACK_GROW(L, 5); 359 STACK_GROW(L_, 5);
360 360
361 int const finalizers_index{ lua_gettop(L) }; 361 int const finalizers_index{ lua_gettop(L_) };
362 int const err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L, lane_error), lua_gettop(L)) : 0 }; 362 int const err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L_, lane_error), lua_gettop(L_)) : 0 };
363 363
364 int rc{ LUA_OK }; 364 int rc{ LUA_OK };
365 for (int n = static_cast<int>(lua_rawlen(L, finalizers_index)); n > 0; --n) 365 for (int n = static_cast<int>(lua_rawlen(L_, finalizers_index)); n > 0; --n)
366 { 366 {
367 int args = 0; 367 int args = 0;
368 lua_pushinteger(L, n); // ... finalizers lane_error n 368 lua_pushinteger(L_, n); // ... finalizers lane_error n
369 lua_rawget(L, finalizers_index); // ... finalizers lane_error finalizer 369 lua_rawget(L_, finalizers_index); // ... finalizers lane_error finalizer
370 LUA_ASSERT(L, lua_isfunction(L, -1)); 370 LUA_ASSERT(L_, lua_isfunction(L_, -1));
371 if (lua_rc_ != LUA_OK) // we have an error message and an optional stack trace at the bottom of the stack 371 if (lua_rc_ != LUA_OK) // we have an error message and an optional stack trace at the bottom of the stack
372 { 372 {
373 LUA_ASSERT(L, finalizers_index == 2 || finalizers_index == 3); 373 LUA_ASSERT(L_, finalizers_index == 2 || finalizers_index == 3);
374 //char const* err_msg = lua_tostring(L, 1); 374 //char const* err_msg = lua_tostring(L, 1);
375 lua_pushvalue(L, 1); // ... finalizers lane_error finalizer err_msg 375 lua_pushvalue(L_, 1); // ... finalizers lane_error finalizer err_msg
376 // note we don't always have a stack trace for example when kCancelError, or when we got an error that doesn't call our handler, such as LUA_ERRMEM 376 // note we don't always have a stack trace for example when kCancelError, or when we got an error that doesn't call our handler, such as LUA_ERRMEM
377 if (finalizers_index == 3) 377 if (finalizers_index == 3)
378 { 378 {
379 lua_pushvalue(L, 2); // ... finalizers lane_error finalizer err_msg stack_trace 379 lua_pushvalue(L_, 2); // ... finalizers lane_error finalizer err_msg stack_trace
380 } 380 }
381 args = finalizers_index - 1; 381 args = finalizers_index - 1;
382 } 382 }
383 383
384 // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace 384 // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace
385 rc = lua_pcall(L, args, 0, err_handler_index); // ... finalizers lane_error err_msg2? 385 rc = lua_pcall(L_, args, 0, err_handler_index); // ... finalizers lane_error err_msg2?
386 if (rc != LUA_OK) 386 if (rc != LUA_OK)
387 { 387 {
388 push_stack_trace(L, rc, lua_gettop(L)); 388 push_stack_trace(L_, rc, lua_gettop(L_));
389 // If one finalizer fails, don't run the others. Return this 389 // If one finalizer fails, don't run the others. Return this
390 // as the 'real' error, replacing what we could have had (or not) 390 // as the 'real' error, replacing what we could have had (or not)
391 // from the actual code. 391 // from the actual code.
@@ -397,18 +397,18 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
397 if (rc != LUA_OK) 397 if (rc != LUA_OK)
398 { 398 {
399 // ERROR_FULL_STACK accounts for the presence of lane_error on the stack 399 // ERROR_FULL_STACK accounts for the presence of lane_error on the stack
400 int const nb_err_slots{ lua_gettop(L) - finalizers_index - ERROR_FULL_STACK }; 400 int const nb_err_slots{ lua_gettop(L_) - finalizers_index - ERROR_FULL_STACK };
401 // a finalizer generated an error, this is what we leave of the stack 401 // a finalizer generated an error, this is what we leave of the stack
402 for (int n = nb_err_slots; n > 0; --n) 402 for (int n = nb_err_slots; n > 0; --n)
403 { 403 {
404 lua_replace(L, n); 404 lua_replace(L_, n);
405 } 405 }
406 // leave on the stack only the error and optional stack trace produced by the error in the finalizer 406 // leave on the stack only the error and optional stack trace produced by the error in the finalizer
407 lua_settop(L, nb_err_slots); 407 lua_settop(L_, nb_err_slots);
408 } 408 }
409 else // no error from the finalizers, make sure only the original return values from the lane body remain on the stack 409 else // no error from the finalizers, make sure only the original return values from the lane body remain on the stack
410 { 410 {
411 lua_settop(L, finalizers_index - 1); 411 lua_settop(L_, finalizers_index - 1);
412 } 412 }
413 413
414 return rc; 414 return rc;
@@ -481,11 +481,11 @@ static void selfdestruct_add(Lane* lane_)
481/* 481/*
482* Process end; cancel any still free-running threads 482* Process end; cancel any still free-running threads
483*/ 483*/
484[[nodiscard]] static int universe_gc(lua_State* L) 484[[nodiscard]] static int universe_gc(lua_State* L_)
485{ 485{
486 Universe* const U{ lua_tofulluserdata<Universe>(L, 1) }; 486 Universe* const U{ lua_tofulluserdata<Universe>(L_, 1) };
487 lua_Duration const shutdown_timeout{ lua_tonumber(L, lua_upvalueindex(1)) }; 487 lua_Duration const shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) };
488 [[maybe_unused]] char const* const op_string{ lua_tostring(L, lua_upvalueindex(2)) }; 488 [[maybe_unused]] char const* const op_string{ lua_tostring(L_, lua_upvalueindex(2)) };
489 CancelOp const op{ which_cancel_op(op_string) }; 489 CancelOp const op{ which_cancel_op(op_string) };
490 490
491 if (U->selfdestruct_first != SELFDESTRUCT_END) 491 if (U->selfdestruct_first != SELFDESTRUCT_END)
@@ -556,7 +556,7 @@ static void selfdestruct_add(Lane* lane_)
556 if (lane != SELFDESTRUCT_END) 556 if (lane != SELFDESTRUCT_END)
557 { 557 {
558 // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) 558 // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it)
559 raise_luaL_error(L, "Zombie thread %s refuses to die!", lane->debug_name); 559 raise_luaL_error(L_, "Zombie thread %s refuses to die!", lane->debug_name);
560 } 560 }
561 } 561 }
562 562
@@ -564,22 +564,22 @@ static void selfdestruct_add(Lane* lane_)
564 if (U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer 564 if (U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer
565 { 565 {
566 [[maybe_unused]] int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) }; 566 [[maybe_unused]] int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) };
567 LUA_ASSERT(L, prev_ref_count == 1); // this should be the last reference 567 LUA_ASSERT(L_, prev_ref_count == 1); // this should be the last reference
568 DeepFactory::DeleteDeepObject(L, U->timer_deep); 568 DeepFactory::DeleteDeepObject(L_, U->timer_deep);
569 U->timer_deep = nullptr; 569 U->timer_deep = nullptr;
570 } 570 }
571 571
572 close_keepers(U); 572 close_keepers(U);
573 573
574 // remove the protected allocator, if any 574 // remove the protected allocator, if any
575 U->protected_allocator.removeFrom(L); 575 U->protected_allocator.removeFrom(L_);
576 576
577 U->Universe::~Universe(); 577 U->Universe::~Universe();
578 578
579 // universe is no longer available (nor necessary) 579 // universe is no longer available (nor necessary)
580 // we need to do this in case some deep userdata objects were created before Lanes was initialized, 580 // we need to do this in case some deep userdata objects were created before Lanes was initialized,
581 // as potentially they will be garbage collected after Lanes at application shutdown 581 // as potentially they will be garbage collected after Lanes at application shutdown
582 universe_store(L, nullptr); 582 universe_store(L_, nullptr);
583 return 0; 583 return 0;
584} 584}
585 585
@@ -593,23 +593,22 @@ static void selfdestruct_add(Lane* lane_)
593// 593//
594LUAG_FUNC( set_singlethreaded) 594LUAG_FUNC( set_singlethreaded)
595{ 595{
596 lua_Integer cores = luaL_optinteger(L, 1, 1); 596 [[maybe_unused]] lua_Integer const cores{ luaL_optinteger(L_, 1, 1) };
597 (void) cores; // prevent "unused" warning
598 597
599#ifdef PLATFORM_OSX 598#ifdef PLATFORM_OSX
600#ifdef _UTILBINDTHREADTOCPU 599#ifdef _UTILBINDTHREADTOCPU
601 if (cores > 1) 600 if (cores > 1)
602 { 601 {
603 raise_luaL_error(L, "Limiting to N>1 cores not possible"); 602 raise_luaL_error(L_, "Limiting to N>1 cores not possible");
604 } 603 }
605 // requires 'chudInitialize()' 604 // requires 'chudInitialize()'
606 utilBindThreadToCPU(0); // # of CPU to run on (we cannot limit to 2..N CPUs?) 605 utilBindThreadToCPU(0); // # of CPU to run on (we cannot limit to 2..N CPUs?)
607 return 0; 606 return 0;
608#else 607#else
609 raise_luaL_error(L, "Not available: compile with _UTILBINDTHREADTOCPU"); 608 raise_luaL_error(L_, "Not available: compile with _UTILBINDTHREADTOCPU");
610#endif 609#endif
611#else 610#else
612 raise_luaL_error(L, "not implemented"); 611 raise_luaL_error(L_, "not implemented");
613#endif 612#endif
614} 613}
615 614
@@ -638,35 +637,35 @@ static constexpr RegistryUniqueKey kExtendedStackTraceRegKey{ 0x38147AD48FB426E2
638 637
639LUAG_FUNC( set_error_reporting) 638LUAG_FUNC( set_error_reporting)
640{ 639{
641 luaL_checktype(L, 1, LUA_TSTRING); 640 luaL_checktype(L_, 1, LUA_TSTRING);
642 char const* mode{ lua_tostring(L, 1) }; 641 char const* mode{ lua_tostring(L_, 1) };
643 lua_pushliteral(L, "extended"); 642 lua_pushliteral(L_, "extended");
644 bool const extended{ strcmp(mode, "extended") == 0 }; 643 bool const extended{ strcmp(mode, "extended") == 0 };
645 bool const basic{ strcmp(mode, "basic") == 0 }; 644 bool const basic{ strcmp(mode, "basic") == 0 };
646 if (!extended && !basic) 645 if (!extended && !basic)
647 { 646 {
648 raise_luaL_error(L, "unsupported error reporting model %s", mode); 647 raise_luaL_error(L_, "unsupported error reporting model %s", mode);
649 } 648 }
650 649
651 kExtendedStackTraceRegKey.setValue(L, [extended](lua_State* L) { lua_pushboolean(L, extended ? 1 : 0); }); 650 kExtendedStackTraceRegKey.setValue(L_, [extended](lua_State* L_) { lua_pushboolean(L_, extended ? 1 : 0); });
652 return 0; 651 return 0;
653} 652}
654 653
655[[nodiscard]] static int lane_error(lua_State* L) 654[[nodiscard]] static int lane_error(lua_State* L_)
656{ 655{
657 // error message (any type) 656 // error message (any type)
658 STACK_CHECK_START_ABS(L, 1); // some_error 657 STACK_CHECK_START_ABS(L_, 1); // some_error
659 658
660 // Don't do stack survey for cancelled lanes. 659 // Don't do stack survey for cancelled lanes.
661 // 660 //
662 if (kCancelError.equals(L, 1)) 661 if (kCancelError.equals(L_, 1))
663 { 662 {
664 return 1; // just pass on 663 return 1; // just pass on
665 } 664 }
666 665
667 STACK_GROW(L, 3); 666 STACK_GROW(L_, 3);
668 bool const extended{ kExtendedStackTraceRegKey.readBoolValue(L) }; 667 bool const extended{ kExtendedStackTraceRegKey.readBoolValue(L_) };
669 STACK_CHECK(L, 1); 668 STACK_CHECK(L_, 1);
670 669
671 // Place stack trace at 'registry[kStackTraceRegKey]' for the 'lua_pcall()' 670 // Place stack trace at 'registry[kStackTraceRegKey]' for the 'lua_pcall()'
672 // caller to fetch. This bypasses the Lua 5.1 limitation of only one 671 // caller to fetch. This bypasses the Lua 5.1 limitation of only one
@@ -678,50 +677,50 @@ LUAG_FUNC( set_error_reporting)
678 // 677 //
679 // table of { "sourcefile.lua:<line>", ... } 678 // table of { "sourcefile.lua:<line>", ... }
680 // 679 //
681 lua_newtable(L); // some_error {} 680 lua_newtable(L_); // some_error {}
682 681
683 // Best to start from level 1, but in some cases it might be a C function 682 // Best to start from level 1, but in some cases it might be a C function
684 // and we don't get '.currentline' for that. It's okay - just keep level 683 // and we don't get '.currentline' for that. It's okay - just keep level
685 // and table index growing separate. --AKa 22-Jan-2009 684 // and table index growing separate. --AKa 22-Jan-2009
686 // 685 //
687 lua_Debug ar; 686 lua_Debug ar;
688 for (int n = 1; lua_getstack(L, n, &ar); ++n) 687 for (int n = 1; lua_getstack(L_, n, &ar); ++n)
689 { 688 {
690 lua_getinfo(L, extended ? "Sln" : "Sl", &ar); 689 lua_getinfo(L_, extended ? "Sln" : "Sl", &ar);
691 if (extended) 690 if (extended)
692 { 691 {
693 lua_newtable(L); // some_error {} {} 692 lua_newtable(L_); // some_error {} {}
694 693
695 lua_pushstring(L, ar.source); // some_error {} {} source 694 lua_pushstring(L_, ar.source); // some_error {} {} source
696 lua_setfield(L, -2, "source"); // some_error {} {} 695 lua_setfield(L_, -2, "source"); // some_error {} {}
697 696
698 lua_pushinteger(L, ar.currentline); // some_error {} {} currentline 697 lua_pushinteger(L_, ar.currentline); // some_error {} {} currentline
699 lua_setfield(L, -2, "currentline"); // some_error {} {} 698 lua_setfield(L_, -2, "currentline"); // some_error {} {}
700 699
701 lua_pushstring(L, ar.name); // some_error {} {} name 700 lua_pushstring(L_, ar.name); // some_error {} {} name
702 lua_setfield(L, -2, "name"); // some_error {} {} 701 lua_setfield(L_, -2, "name"); // some_error {} {}
703 702
704 lua_pushstring(L, ar.namewhat); // some_error {} {} namewhat 703 lua_pushstring(L_, ar.namewhat); // some_error {} {} namewhat
705 lua_setfield(L, -2, "namewhat"); // some_error {} {} 704 lua_setfield(L_, -2, "namewhat"); // some_error {} {}
706 705
707 lua_pushstring(L, ar.what); // some_error {} {} what 706 lua_pushstring(L_, ar.what); // some_error {} {} what
708 lua_setfield(L, -2, "what"); // some_error {} {} 707 lua_setfield(L_, -2, "what"); // some_error {} {}
709 } 708 }
710 else if (ar.currentline > 0) 709 else if (ar.currentline > 0)
711 { 710 {
712 lua_pushfstring(L, "%s:%d", ar.short_src, ar.currentline); // some_error {} "blah:blah" 711 lua_pushfstring(L_, "%s:%d", ar.short_src, ar.currentline); // some_error {} "blah:blah"
713 } 712 }
714 else 713 else
715 { 714 {
716 lua_pushfstring(L, "%s:?", ar.short_src); // some_error {} "blah" 715 lua_pushfstring(L_, "%s:?", ar.short_src); // some_error {} "blah"
717 } 716 }
718 lua_rawseti(L, -2, (lua_Integer) n); // some_error {} 717 lua_rawseti(L_, -2, (lua_Integer) n); // some_error {}
719 } 718 }
720 719
721 // store the stack trace table in the registry 720 // store the stack trace table in the registry
722 kStackTraceRegKey.setValue(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error 721 kStackTraceRegKey.setValue(L_, [](lua_State* L_) { lua_insert(L_, -2); }); // some_error
723 722
724 STACK_CHECK(L, 1); 723 STACK_CHECK(L_, 1);
725 return 1; // the untouched error value 724 return 1; // the untouched error value
726} 725}
727#endif // ERROR_FULL_STACK 726#endif // ERROR_FULL_STACK
@@ -733,19 +732,19 @@ LUAG_FUNC(set_debug_threadname)
733 // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator 732 // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator
734 constexpr RegistryUniqueKey hidden_regkey{ 0x79C0669AAAE04440ull }; 733 constexpr RegistryUniqueKey hidden_regkey{ 0x79C0669AAAE04440ull };
735 // C s_lane structure is a light userdata upvalue 734 // C s_lane structure is a light userdata upvalue
736 Lane* const lane{ lua_tolightuserdata<Lane>(L, lua_upvalueindex(1)) }; 735 Lane* const lane{ lua_tolightuserdata<Lane>(L_, lua_upvalueindex(1)) };
737 luaL_checktype(L, -1, LUA_TSTRING); // "name" 736 luaL_checktype(L_, -1, LUA_TSTRING); // "name"
738 lua_settop(L, 1); 737 lua_settop(L_, 1);
739 STACK_CHECK_START_ABS(L, 1); 738 STACK_CHECK_START_ABS(L_, 1);
740 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... 739 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global...
741 hidden_regkey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 740 hidden_regkey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); });
742 STACK_CHECK(L, 1); 741 STACK_CHECK(L_, 1);
743 lane->debug_name = lua_tostring(L, -1); 742 lane->debug_name = lua_tostring(L_, -1);
744 // keep a direct pointer on the string 743 // keep a direct pointer on the string
745 THREAD_SETNAME(lane->debug_name); 744 THREAD_SETNAME(lane->debug_name);
746 // to see VM name in Decoda debugger Virtual Machine window 745 // to see VM name in Decoda debugger Virtual Machine window
747 lua_setglobal(L, "decoda_name"); // 746 lua_setglobal(L_, "decoda_name"); //
748 STACK_CHECK(L, 0); 747 STACK_CHECK(L_, 0);
749 return 0; 748 return 0;
750} 749}
751 750
@@ -753,9 +752,9 @@ LUAG_FUNC(set_debug_threadname)
753 752
754LUAG_FUNC(get_debug_threadname) 753LUAG_FUNC(get_debug_threadname)
755{ 754{
756 Lane* const lane{ ToLane(L, 1) }; 755 Lane* const lane{ ToLane(L_, 1) };
757 luaL_argcheck(L, lua_gettop(L) == 1, 2, "too many arguments"); 756 luaL_argcheck(L_, lua_gettop(L_) == 1, 2, "too many arguments");
758 lua_pushstring(L, lane->debug_name); 757 lua_pushstring(L_, lane->debug_name);
759 return 1; 758 return 1;
760} 759}
761 760
@@ -763,15 +762,15 @@ LUAG_FUNC(get_debug_threadname)
763 762
764LUAG_FUNC(set_thread_priority) 763LUAG_FUNC(set_thread_priority)
765{ 764{
766 lua_Integer const prio{ luaL_checkinteger(L, 1) }; 765 lua_Integer const prio{ luaL_checkinteger(L_, 1) };
767 // public Lanes API accepts a generic range -3/+3 766 // public Lanes API accepts a generic range -3/+3
768 // that will be remapped into the platform-specific scheduler priority scheme 767 // that will be remapped into the platform-specific scheduler priority scheme
769 // On some platforms, -3 is equivalent to -2 and +3 to +2 768 // On some platforms, -3 is equivalent to -2 and +3 to +2
770 if (prio < kThreadPrioMin || prio > kThreadPrioMax) 769 if (prio < kThreadPrioMin || prio > kThreadPrioMax)
771 { 770 {
772 raise_luaL_error(L, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio); 771 raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio);
773 } 772 }
774 THREAD_SET_PRIORITY(static_cast<int>(prio), universe_get(L)->m_sudo); 773 THREAD_SET_PRIORITY(static_cast<int>(prio), universe_get(L_)->m_sudo);
775 return 0; 774 return 0;
776} 775}
777 776
@@ -779,10 +778,10 @@ LUAG_FUNC(set_thread_priority)
779 778
780LUAG_FUNC(set_thread_affinity) 779LUAG_FUNC(set_thread_affinity)
781{ 780{
782 lua_Integer const affinity{ luaL_checkinteger(L, 1) }; 781 lua_Integer const affinity{ luaL_checkinteger(L_, 1) };
783 if (affinity <= 0) 782 if (affinity <= 0)
784 { 783 {
785 raise_luaL_error(L, "invalid affinity (%d)", affinity); 784 raise_luaL_error(L_, "invalid affinity (%d)", affinity);
786 } 785 }
787 THREAD_SET_AFFINITY( static_cast<unsigned int>(affinity)); 786 THREAD_SET_AFFINITY( static_cast<unsigned int>(affinity));
788 return 0; 787 return 0;
@@ -920,18 +919,18 @@ static void lane_main(Lane* lane)
920// upvalue[1]: _G.require 919// upvalue[1]: _G.require
921LUAG_FUNC(require) 920LUAG_FUNC(require)
922{ 921{
923 char const* name = lua_tostring(L, 1); 922 char const* name = lua_tostring(L_, 1);
924 int const nargs = lua_gettop(L); 923 int const nargs = lua_gettop(L_);
925 DEBUGSPEW_CODE(Universe* U = universe_get(L)); 924 DEBUGSPEW_CODE(Universe* U = universe_get(L_));
926 STACK_CHECK_START_REL(L, 0); 925 STACK_CHECK_START_REL(L_, 0);
927 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); 926 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name));
928 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 927 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
929 lua_pushvalue(L, lua_upvalueindex(1)); // "name" require 928 lua_pushvalue(L_, lua_upvalueindex(1)); // "name" require
930 lua_insert(L, 1); // require "name" 929 lua_insert(L_, 1); // require "name"
931 lua_call(L, nargs, 1); // module 930 lua_call(L_, nargs, 1); // module
932 populate_func_lookup_table(L, -1, name); 931 populate_func_lookup_table(L_, -1, name);
933 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END, name)); 932 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END, name));
934 STACK_CHECK(L, 0); 933 STACK_CHECK(L_, 0);
935 return 1; 934 return 1;
936} 935}
937 936
@@ -942,18 +941,18 @@ LUAG_FUNC(require)
942// lanes.register( "modname", module) 941// lanes.register( "modname", module)
943LUAG_FUNC(register) 942LUAG_FUNC(register)
944{ 943{
945 char const* name = luaL_checkstring(L, 1); 944 char const* name = luaL_checkstring(L_, 1);
946 LuaType const mod_type{ lua_type_as_enum(L, 2) }; 945 LuaType const mod_type{ lua_type_as_enum(L_, 2) };
947 // ignore extra parameters, just in case 946 // ignore extra parameters, just in case
948 lua_settop(L, 2); 947 lua_settop(L_, 2);
949 luaL_argcheck(L, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type"); 948 luaL_argcheck(L_, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type");
950 DEBUGSPEW_CODE(Universe* U = universe_get(L)); 949 DEBUGSPEW_CODE(Universe* U = universe_get(L));
951 STACK_CHECK_START_REL(L, 0); // "name" mod_table 950 STACK_CHECK_START_REL(L_, 0); // "name" mod_table
952 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); 951 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name));
953 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 952 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
954 populate_func_lookup_table(L, -1, name); 953 populate_func_lookup_table(L_, -1, name);
955 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END, name)); 954 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END, name));
956 STACK_CHECK(L, 0); 955 STACK_CHECK(L_, 0);
957 return 0; 956 return 0;
958} 957}
959 958
@@ -976,38 +975,38 @@ static constexpr UniqueKey kLaneGC{ 0x5D6122141727F960ull };
976// 975//
977LUAG_FUNC(lane_new) 976LUAG_FUNC(lane_new)
978{ 977{
979 char const* const libs_str{ lua_tostring(L, 2) }; 978 char const* const libs_str{ lua_tostring(L_, 2) };
980 bool const have_priority{ !lua_isnoneornil(L, 3) }; 979 bool const have_priority{ !lua_isnoneornil(L_, 3) };
981 int const priority{ have_priority ? (int) lua_tointeger(L, 3) : kThreadPrioDefault }; 980 int const priority{ have_priority ? static_cast<int>(lua_tointeger(L_, 3)) : kThreadPrioDefault };
982 int const globals_idx{ lua_isnoneornil(L, 4) ? 0 : 4 }; 981 int const globals_idx{ lua_isnoneornil(L_, 4) ? 0 : 4 };
983 int const package_idx{ lua_isnoneornil(L, 5) ? 0 : 5 }; 982 int const package_idx{ lua_isnoneornil(L_, 5) ? 0 : 5 };
984 int const required_idx{ lua_isnoneornil(L, 6) ? 0 : 6 }; 983 int const required_idx{ lua_isnoneornil(L_, 6) ? 0 : 6 };
985 int const gc_cb_idx{ lua_isnoneornil(L, 7) ? 0 : 7 }; 984 int const gc_cb_idx{ lua_isnoneornil(L_, 7) ? 0 : 7 };
986 985
987 static constexpr int kFixedArgsIdx{ 7 }; 986 static constexpr int kFixedArgsIdx{ 7 };
988 int const nargs{ lua_gettop(L) - kFixedArgsIdx }; 987 int const nargs{ lua_gettop(L_) - kFixedArgsIdx };
989 Universe* const U{ universe_get(L) }; 988 Universe* const U{ universe_get(L_) };
990 LUA_ASSERT(L, nargs >= 0); 989 LUA_ASSERT(L_, nargs >= 0);
991 990
992 // public Lanes API accepts a generic range -3/+3 991 // public Lanes API accepts a generic range -3/+3
993 // that will be remapped into the platform-specific scheduler priority scheme 992 // that will be remapped into the platform-specific scheduler priority scheme
994 // On some platforms, -3 is equivalent to -2 and +3 to +2 993 // On some platforms, -3 is equivalent to -2 and +3 to +2
995 if (have_priority && (priority < kThreadPrioMin || priority > kThreadPrioMax)) 994 if (have_priority && (priority < kThreadPrioMin || priority > kThreadPrioMax))
996 { 995 {
997 raise_luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority); 996 raise_luaL_error(L_, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority);
998 } 997 }
999 998
1000 /* --- Create and prepare the sub state --- */ 999 /* --- Create and prepare the sub state --- */
1001 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END)); 1000 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END));
1002 1001
1003 // populate with selected libraries at the same time 1002 // populate with selected libraries at the same time
1004 lua_State* const L2{ luaG_newstate(U, SourceState{ L }, libs_str) }; // L // L2 1003 lua_State* const L2{ luaG_newstate(U, SourceState{ L_ }, libs_str) }; // L // L2
1005 1004
1006 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1005 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1007 Lane* const lane{ new (U) Lane{ U, L2 } }; 1006 Lane* const lane{ new (U) Lane{ U, L2 } };
1008 if (lane == nullptr) 1007 if (lane == nullptr)
1009 { 1008 {
1010 raise_luaL_error(L, "could not create lane: out of memory"); 1009 raise_luaL_error(L_, "could not create lane: out of memory");
1011 } 1010 }
1012 1011
1013 class OnExit 1012 class OnExit
@@ -1090,7 +1089,7 @@ LUAG_FUNC(lane_new)
1090 m_lane->m_ready.count_down(); 1089 m_lane->m_ready.count_down();
1091 m_lane = nullptr; 1090 m_lane = nullptr;
1092 } 1091 }
1093 } onExit{ L, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) }; 1092 } onExit{ L_, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) };
1094 // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation 1093 // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation
1095 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); 1094 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END));
1096 lane->startThread(priority); 1095 lane->startThread(priority);
@@ -1098,22 +1097,22 @@ LUAG_FUNC(lane_new)
1098 STACK_GROW( L2, nargs + 3); // 1097 STACK_GROW( L2, nargs + 3); //
1099 STACK_CHECK_START_REL(L2, 0); 1098 STACK_CHECK_START_REL(L2, 0);
1100 1099
1101 STACK_GROW(L, 3); // func libs priority globals package required gc_cb [... args ...] 1100 STACK_GROW(L_, 3); // func libs priority globals package required gc_cb [... args ...]
1102 STACK_CHECK_START_REL(L, 0); 1101 STACK_CHECK_START_REL(L_, 0);
1103 1102
1104 // give a default "Lua" name to the thread to see VM name in Decoda debugger 1103 // give a default "Lua" name to the thread to see VM name in Decoda debugger
1105 lua_pushfstring( L2, "Lane #%p", L2); // "..." 1104 lua_pushfstring( L2, "Lane #%p", L2); // "..."
1106 lua_setglobal( L2, "decoda_name"); // 1105 lua_setglobal( L2, "decoda_name"); //
1107 LUA_ASSERT(L, lua_gettop( L2) == 0); 1106 LUA_ASSERT(L_, lua_gettop( L2) == 0);
1108 1107
1109 // package 1108 // package
1110 if (package_idx != 0) 1109 if (package_idx != 0)
1111 { 1110 {
1112 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END)); 1111 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END));
1113 // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack 1112 // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack
1114 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, SourceIndex{ package_idx }, {}, {}, {} }; 1113 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, SourceIndex{ package_idx }, {}, {}, {} };
1115 [[maybe_unused]] InterCopyResult const ret{ c.inter_copy_package() }; 1114 [[maybe_unused]] InterCopyResult const ret{ c.inter_copy_package() };
1116 LUA_ASSERT(L, ret == InterCopyResult::Success); // either all went well, or we should not even get here 1115 LUA_ASSERT(L_, ret == InterCopyResult::Success); // either all went well, or we should not even get here
1117 } 1116 }
1118 1117
1119 // modules to require in the target lane *before* the function is transfered! 1118 // modules to require in the target lane *before* the function is transfered!
@@ -1123,23 +1122,23 @@ LUAG_FUNC(lane_new)
1123 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require 'required' list\n" INDENT_END)); 1122 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require 'required' list\n" INDENT_END));
1124 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 1123 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
1125 // should not happen, was checked in lanes.lua before calling lane_new() 1124 // should not happen, was checked in lanes.lua before calling lane_new()
1126 if (lua_type(L, required_idx) != LUA_TTABLE) 1125 if (lua_type(L_, required_idx) != LUA_TTABLE)
1127 { 1126 {
1128 raise_luaL_error(L, "expected required module list as a table, got %s", luaL_typename(L, required_idx)); 1127 raise_luaL_error(L_, "expected required module list as a table, got %s", luaL_typename(L_, required_idx));
1129 } 1128 }
1130 1129
1131 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil 1130 lua_pushnil(L_); // func libs priority globals package required gc_cb [... args ...] nil
1132 while (lua_next(L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" 1131 while (lua_next(L_, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname"
1133 { 1132 {
1134 if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired) 1133 if (lua_type(L_, -1) != LUA_TSTRING || lua_type(L_, -2) != LUA_TNUMBER || lua_tonumber(L_, -2) != nbRequired)
1135 { 1134 {
1136 raise_luaL_error(L, "required module list should be a list of strings"); 1135 raise_luaL_error(L_, "required module list should be a list of strings");
1137 } 1136 }
1138 else 1137 else
1139 { 1138 {
1140 // require the module in the target state, and populate the lookup table there too 1139 // require the module in the target state, and populate the lookup table there too
1141 size_t len; 1140 size_t len;
1142 char const* name = lua_tolstring(L, -1, &len); 1141 char const* name = lua_tolstring(L_, -1, &len);
1143 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); 1142 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name));
1144 1143
1145 // require the module in the target lane 1144 // require the module in the target lane
@@ -1147,7 +1146,7 @@ LUAG_FUNC(lane_new)
1147 if (lua_isnil( L2, -1)) 1146 if (lua_isnil( L2, -1))
1148 { 1147 {
1149 lua_pop( L2, 1); // 1148 lua_pop( L2, 1); //
1150 raise_luaL_error(L, "cannot pre-require modules without loading 'package' library first"); 1149 raise_luaL_error(L_, "cannot pre-require modules without loading 'package' library first");
1151 } 1150 }
1152 else 1151 else
1153 { 1152 {
@@ -1155,20 +1154,20 @@ LUAG_FUNC(lane_new)
1155 if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode 1154 if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode
1156 { 1155 {
1157 // propagate error to main state if any 1156 // propagate error to main state if any
1158 InterCopyContext c{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }; 1157 InterCopyContext c{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} };
1159 std::ignore = c.inter_move(1); // func libs priority globals package required gc_cb [... args ...] n "modname" error 1158 std::ignore = c.inter_move(1); // func libs priority globals package required gc_cb [... args ...] n "modname" error
1160 raise_lua_error(L); 1159 raise_lua_error(L_);
1161 } 1160 }
1162 // after requiring the module, register the functions it exported in our name<->function database 1161 // after requiring the module, register the functions it exported in our name<->function database
1163 populate_func_lookup_table( L2, -1, name); 1162 populate_func_lookup_table( L2, -1, name);
1164 lua_pop( L2, 1); // 1163 lua_pop( L2, 1); //
1165 } 1164 }
1166 } 1165 }
1167 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] n 1166 lua_pop(L_, 1); // func libs priority globals package required gc_cb [... args ...] n
1168 ++ nbRequired; 1167 ++ nbRequired;
1169 } // func libs priority globals package required gc_cb [... args ...] 1168 } // func libs priority globals package required gc_cb [... args ...]
1170 } 1169 }
1171 STACK_CHECK(L, 0); 1170 STACK_CHECK(L_, 0);
1172 STACK_CHECK(L2, 0); // 1171 STACK_CHECK(L2, 0); //
1173 1172
1174 // Appending the specified globals to the global environment 1173 // Appending the specified globals to the global environment
@@ -1177,83 +1176,83 @@ LUAG_FUNC(lane_new)
1177 if (globals_idx != 0) 1176 if (globals_idx != 0)
1178 { 1177 {
1179 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer globals\n" INDENT_END)); 1178 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer globals\n" INDENT_END));
1180 if (!lua_istable(L, globals_idx)) 1179 if (!lua_istable(L_, globals_idx))
1181 { 1180 {
1182 raise_luaL_error(L, "Expected table, got %s", luaL_typename(L, globals_idx)); 1181 raise_luaL_error(L_, "Expected table, got %s", luaL_typename(L_, globals_idx));
1183 } 1182 }
1184 1183
1185 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 1184 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
1186 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil 1185 lua_pushnil(L_); // func libs priority globals package required gc_cb [... args ...] nil
1187 // Lua 5.2 wants us to push the globals table on the stack 1186 // Lua 5.2 wants us to push the globals table on the stack
1188 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, {}, {}, {}, {} }; 1187 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} };
1189 lua_pushglobaltable(L2); // _G 1188 lua_pushglobaltable(L2); // _G
1190 while( lua_next(L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v 1189 while( lua_next(L_, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v
1191 { 1190 {
1192 std::ignore = c.inter_copy(2); // _G k v 1191 std::ignore = c.inter_copy(2); // _G k v
1193 // assign it in L2's globals table 1192 // assign it in L2's globals table
1194 lua_rawset(L2, -3); // _G 1193 lua_rawset(L2, -3); // _G
1195 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] k 1194 lua_pop(L_, 1); // func libs priority globals package required gc_cb [... args ...] k
1196 } // func libs priority globals package required gc_cb [... args ...] 1195 } // func libs priority globals package required gc_cb [... args ...]
1197 lua_pop( L2, 1); // 1196 lua_pop( L2, 1); //
1198 } 1197 }
1199 STACK_CHECK(L, 0); 1198 STACK_CHECK(L_, 0);
1200 STACK_CHECK(L2, 0); 1199 STACK_CHECK(L2, 0);
1201 1200
1202 // Lane main function 1201 // Lane main function
1203 LuaType const func_type{ lua_type_as_enum(L, 1) }; 1202 LuaType const func_type{ lua_type_as_enum(L_, 1) };
1204 if (func_type == LuaType::FUNCTION) 1203 if (func_type == LuaType::FUNCTION)
1205 { 1204 {
1206 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); 1205 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END));
1207 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 1206 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
1208 lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func 1207 lua_pushvalue(L_, 1); // func libs priority globals package required gc_cb [... args ...] func
1209 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, {}, {}, {}, {} }; 1208 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} };
1210 InterCopyResult const res{ c.inter_move(1) }; // func libs priority globals package required gc_cb [... args ...] // func 1209 InterCopyResult const res{ c.inter_move(1) }; // func libs priority globals package required gc_cb [... args ...] // func
1211 if (res != InterCopyResult::Success) 1210 if (res != InterCopyResult::Success)
1212 { 1211 {
1213 raise_luaL_error(L, "tried to copy unsupported types"); 1212 raise_luaL_error(L_, "tried to copy unsupported types");
1214 } 1213 }
1215 } 1214 }
1216 else if (func_type == LuaType::STRING) 1215 else if (func_type == LuaType::STRING)
1217 { 1216 {
1218 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END)); 1217 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END));
1219 // compile the string 1218 // compile the string
1220 if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func 1219 if (luaL_loadstring(L2, lua_tostring(L_, 1)) != 0) // func
1221 { 1220 {
1222 raise_luaL_error(L, "error when parsing lane function code"); 1221 raise_luaL_error(L_, "error when parsing lane function code");
1223 } 1222 }
1224 } 1223 }
1225 else 1224 else
1226 { 1225 {
1227 raise_luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); 1226 raise_luaL_error(L_, "Expected function, got %s", lua_typename(L_, func_type));
1228 } 1227 }
1229 STACK_CHECK(L, 0); 1228 STACK_CHECK(L_, 0);
1230 STACK_CHECK(L2, 1); 1229 STACK_CHECK(L2, 1);
1231 LUA_ASSERT(L, lua_isfunction(L2, 1)); 1230 LUA_ASSERT(L_, lua_isfunction(L2, 1));
1232 1231
1233 // revive arguments 1232 // revive arguments
1234 if (nargs > 0) 1233 if (nargs > 0)
1235 { 1234 {
1236 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); 1235 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END));
1237 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 1236 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
1238 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L }, {}, {}, {}, {}, {} }; 1237 InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} };
1239 InterCopyResult const res{ c.inter_move(nargs) }; // func libs priority globals package required gc_cb // func [... args ...] 1238 InterCopyResult const res{ c.inter_move(nargs) }; // func libs priority globals package required gc_cb // func [... args ...]
1240 if (res != InterCopyResult::Success) 1239 if (res != InterCopyResult::Success)
1241 { 1240 {
1242 raise_luaL_error(L, "tried to copy unsupported types"); 1241 raise_luaL_error(L_, "tried to copy unsupported types");
1243 } 1242 }
1244 } 1243 }
1245 STACK_CHECK(L, -nargs); 1244 STACK_CHECK(L_, -nargs);
1246 LUA_ASSERT(L, lua_gettop(L) == kFixedArgsIdx); 1245 LUA_ASSERT(L_, lua_gettop(L_) == kFixedArgsIdx);
1247 1246
1248 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). 1247 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
1249 kLanePointerRegKey.setValue(L2, [lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); }); // func [... args ...] 1248 kLanePointerRegKey.setValue(L2, [lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); }); // func [... args ...]
1250 STACK_CHECK(L2, 1 + nargs); 1249 STACK_CHECK(L2, 1 + nargs);
1251 1250
1252 STACK_CHECK_RESET_REL(L, 0); 1251 STACK_CHECK_RESET_REL(L_, 0);
1253 // all went well, the lane's thread can start working 1252 // all went well, the lane's thread can start working
1254 onExit.success(); 1253 onExit.success();
1255 // we should have the lane userdata on top of the stack 1254 // we should have the lane userdata on top of the stack
1256 STACK_CHECK(L, 1); 1255 STACK_CHECK(L_, 1);
1257 return 1; 1256 return 1;
1258} 1257}
1259 1258
@@ -1271,24 +1270,24 @@ LUAG_FUNC(lane_new)
1271// and the issue of canceling/killing threads at gc is not very nice, either 1270// and the issue of canceling/killing threads at gc is not very nice, either
1272// (would easily cause waits at gc cycle, which we don't want). 1271// (would easily cause waits at gc cycle, which we don't want).
1273// 1272//
1274[[nodiscard]] static int lane_gc(lua_State* L) 1273[[nodiscard]] static int lane_gc(lua_State* L_)
1275{ 1274{
1276 bool have_gc_cb{ false }; 1275 bool have_gc_cb{ false };
1277 Lane* const lane{ ToLane(L, 1) }; // ud 1276 Lane* const lane{ ToLane(L_, 1) }; // ud
1278 1277
1279 // if there a gc callback? 1278 // if there a gc callback?
1280 lua_getiuservalue(L, 1, 1); // ud uservalue 1279 lua_getiuservalue(L_, 1, 1); // ud uservalue
1281 kLaneGC.pushKey(L); // ud uservalue __gc 1280 kLaneGC.pushKey(L_); // ud uservalue __gc
1282 lua_rawget(L, -2); // ud uservalue gc_cb|nil 1281 lua_rawget(L_, -2); // ud uservalue gc_cb|nil
1283 if (!lua_isnil(L, -1)) 1282 if (!lua_isnil(L_, -1))
1284 { 1283 {
1285 lua_remove(L, -2); // ud gc_cb|nil 1284 lua_remove(L_, -2); // ud gc_cb|nil
1286 lua_pushstring(L, lane->debug_name); // ud gc_cb name 1285 lua_pushstring(L_, lane->debug_name); // ud gc_cb name
1287 have_gc_cb = true; 1286 have_gc_cb = true;
1288 } 1287 }
1289 else 1288 else
1290 { 1289 {
1291 lua_pop(L, 2); // ud 1290 lua_pop(L_, 2); // ud
1292 } 1291 }
1293 1292
1294 // We can read 'lane->status' without locks, but not wait for it 1293 // We can read 'lane->status' without locks, but not wait for it
@@ -1299,8 +1298,8 @@ LUAG_FUNC(lane_new)
1299 assert(lane->selfdestruct_next); 1298 assert(lane->selfdestruct_next);
1300 if (have_gc_cb) 1299 if (have_gc_cb)
1301 { 1300 {
1302 lua_pushliteral(L, "selfdestruct"); // ud gc_cb name status 1301 lua_pushliteral(L_, "selfdestruct"); // ud gc_cb name status
1303 lua_call(L, 2, 0); // ud 1302 lua_call(L_, 2, 0); // ud
1304 } 1303 }
1305 return 0; 1304 return 0;
1306 } 1305 }
@@ -1319,8 +1318,8 @@ LUAG_FUNC(lane_new)
1319 // do this after lane cleanup in case the callback triggers an error 1318 // do this after lane cleanup in case the callback triggers an error
1320 if (have_gc_cb) 1319 if (have_gc_cb)
1321 { 1320 {
1322 lua_pushliteral(L, "closed"); // ud gc_cb name status 1321 lua_pushliteral(L_, "closed"); // ud gc_cb name status
1323 lua_call(L, 2, 0); // ud 1322 lua_call(L_, 2, 0); // ud
1324 } 1323 }
1325 return 0; 1324 return 0;
1326} 1325}
@@ -1374,27 +1373,27 @@ void Lane::pushThreadStatus(lua_State* L_)
1374// 1373//
1375LUAG_FUNC(thread_join) 1374LUAG_FUNC(thread_join)
1376{ 1375{
1377 Lane* const lane{ ToLane(L, 1) }; 1376 Lane* const lane{ ToLane(L_, 1) };
1378 lua_Duration const duration{ luaL_optnumber(L, 2, -1.0) }; 1377 lua_Duration const duration{ luaL_optnumber(L_, 2, -1.0) };
1379 lua_State* const L2{ lane->L }; 1378 lua_State* const L2{ lane->L };
1380 1379
1381 bool const done{ !lane->m_thread.joinable() || lane->waitForCompletion(duration) }; 1380 bool const done{ !lane->m_thread.joinable() || lane->waitForCompletion(duration) };
1382 if (!done || !L2) 1381 if (!done || !L2)
1383 { 1382 {
1384 STACK_GROW(L, 2); 1383 STACK_GROW(L_, 2);
1385 lua_pushnil(L); 1384 lua_pushnil(L_);
1386 lua_pushliteral(L, "timeout"); 1385 lua_pushliteral(L_, "timeout");
1387 return 2; 1386 return 2;
1388 } 1387 }
1389 1388
1390 STACK_CHECK_START_REL(L, 0); 1389 STACK_CHECK_START_REL(L_, 0);
1391 // Thread is Done/Error/Cancelled; all ours now 1390 // Thread is Done/Error/Cancelled; all ours now
1392 1391
1393 int ret{ 0 }; 1392 int ret{ 0 };
1394 Universe* const U{ lane->U }; 1393 Universe* const U{ lane->U };
1395 // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed 1394 // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed
1396 // so store it in the userdata uservalue at a key that can't possibly collide 1395 // so store it in the userdata uservalue at a key that can't possibly collide
1397 securize_debug_threadname(L, lane); 1396 securize_debug_threadname(L_, lane);
1398 switch (lane->m_status) 1397 switch (lane->m_status)
1399 { 1398 {
1400 case Lane::Done: 1399 case Lane::Done:
@@ -1402,10 +1401,10 @@ LUAG_FUNC(thread_join)
1402 int const n{ lua_gettop(L2) }; // whole L2 stack 1401 int const n{ lua_gettop(L2) }; // whole L2 stack
1403 if ( 1402 if (
1404 (n > 0) && 1403 (n > 0) &&
1405 (InterCopyContext{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success) 1404 (InterCopyContext{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success)
1406 ) 1405 )
1407 { 1406 {
1408 raise_luaL_error(L, "tried to copy unsupported types"); 1407 raise_luaL_error(L_, "tried to copy unsupported types");
1409 } 1408 }
1410 ret = n; 1409 ret = n;
1411 } 1410 }
@@ -1414,13 +1413,13 @@ LUAG_FUNC(thread_join)
1414 case Lane::Error: 1413 case Lane::Error:
1415 { 1414 {
1416 int const n{ lua_gettop(L2) }; 1415 int const n{ lua_gettop(L2) };
1417 STACK_GROW(L, 3); 1416 STACK_GROW(L_, 3);
1418 lua_pushnil(L); 1417 lua_pushnil(L_);
1419 // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... 1418 // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ...
1420 InterCopyContext c{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }; 1419 InterCopyContext c{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} };
1421 if (c.inter_move(n) != InterCopyResult::Success) // nil "err" [trace] 1420 if (c.inter_move(n) != InterCopyResult::Success) // nil "err" [trace]
1422 { 1421 {
1423 raise_luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n)); 1422 raise_luaL_error(L_, "tried to copy unsupported types: %s", lua_tostring(L_, -n));
1424 } 1423 }
1425 ret = 1 + n; 1424 ret = 1 + n;
1426 } 1425 }
@@ -1432,12 +1431,12 @@ LUAG_FUNC(thread_join)
1432 1431
1433 default: 1432 default:
1434 DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->m_status)); 1433 DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->m_status));
1435 LUA_ASSERT(L, false); 1434 LUA_ASSERT(L_, false);
1436 ret = 0; 1435 ret = 0;
1437 } 1436 }
1438 lua_close(L2); 1437 lua_close(L2);
1439 lane->L = nullptr; 1438 lane->L = nullptr;
1440 STACK_CHECK(L, ret); 1439 STACK_CHECK(L_, ret);
1441 return ret; 1440 return ret;
1442} 1441}
1443 1442
@@ -1454,60 +1453,60 @@ LUAG_FUNC(thread_index)
1454{ 1453{
1455 static constexpr int kSelf{ 1 }; 1454 static constexpr int kSelf{ 1 };
1456 static constexpr int kKey{ 2 }; 1455 static constexpr int kKey{ 2 };
1457 Lane* const lane{ ToLane(L, kSelf) }; 1456 Lane* const lane{ ToLane(L_, kSelf) };
1458 LUA_ASSERT(L, lua_gettop(L) == 2); 1457 LUA_ASSERT(L_, lua_gettop(L_) == 2);
1459 1458
1460 STACK_GROW(L, 8); // up to 8 positions are needed in case of error propagation 1459 STACK_GROW(L_, 8); // up to 8 positions are needed in case of error propagation
1461 1460
1462 // If key is numeric, wait until the thread returns and populate the environment with the return values 1461 // If key is numeric, wait until the thread returns and populate the environment with the return values
1463 if (lua_type(L, kKey) == LUA_TNUMBER) 1462 if (lua_type(L_, kKey) == LUA_TNUMBER)
1464 { 1463 {
1465 static constexpr int kUsr{ 3 }; 1464 static constexpr int kUsr{ 3 };
1466 // first, check that we don't already have an environment that holds the requested value 1465 // first, check that we don't already have an environment that holds the requested value
1467 { 1466 {
1468 // If key is found in the uservalue, return it 1467 // If key is found in the uservalue, return it
1469 lua_getiuservalue(L, kSelf, 1); 1468 lua_getiuservalue(L_, kSelf, 1);
1470 lua_pushvalue(L, kKey); 1469 lua_pushvalue(L_, kKey);
1471 lua_rawget(L, kUsr); 1470 lua_rawget(L_, kUsr);
1472 if (!lua_isnil(L, -1)) 1471 if (!lua_isnil(L_, -1))
1473 { 1472 {
1474 return 1; 1473 return 1;
1475 } 1474 }
1476 lua_pop(L, 1); 1475 lua_pop(L_, 1);
1477 } 1476 }
1478 { 1477 {
1479 // check if we already fetched the values from the thread or not 1478 // check if we already fetched the values from the thread or not
1480 lua_pushinteger(L, 0); 1479 lua_pushinteger(L_, 0);
1481 lua_rawget(L, kUsr); 1480 lua_rawget(L_, kUsr);
1482 bool const fetched{ !lua_isnil(L, -1) }; 1481 bool const fetched{ !lua_isnil(L_, -1) };
1483 lua_pop(L, 1); // back to our 2 args + uservalue on the stack 1482 lua_pop(L_, 1); // back to our 2 args + uservalue on the stack
1484 if (!fetched) 1483 if (!fetched)
1485 { 1484 {
1486 lua_pushinteger(L, 0); 1485 lua_pushinteger(L_, 0);
1487 lua_pushboolean(L, 1); 1486 lua_pushboolean(L_, 1);
1488 lua_rawset(L, kUsr); 1487 lua_rawset(L_, kUsr);
1489 // wait until thread has completed 1488 // wait until thread has completed
1490 lua_pushcfunction(L, LG_thread_join); 1489 lua_pushcfunction(L_, LG_thread_join);
1491 lua_pushvalue(L, kSelf); 1490 lua_pushvalue(L_, kSelf);
1492 lua_call(L, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ 1491 lua_call(L_, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+
1493 switch (lane->m_status) 1492 switch (lane->m_status)
1494 { 1493 {
1495 default: 1494 default:
1496 // this is an internal error, we probably never get here 1495 // this is an internal error, we probably never get here
1497 lua_settop(L, 0); 1496 lua_settop(L_, 0);
1498 lua_pushliteral(L, "Unexpected status: "); 1497 lua_pushliteral(L_, "Unexpected status: ");
1499 lua_pushstring(L, thread_status_string(lane->m_status)); 1498 lua_pushstring(L_, thread_status_string(lane->m_status));
1500 lua_concat(L, 2); 1499 lua_concat(L_, 2);
1501 raise_lua_error(L); 1500 raise_lua_error(L_);
1502 [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack 1501 [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack
1503 1502
1504 case Lane::Done: // got regular return values 1503 case Lane::Done: // got regular return values
1505 { 1504 {
1506 int const nvalues{ lua_gettop(L) - 3 }; 1505 int const nvalues{ lua_gettop(L_) - 3 };
1507 for (int i = nvalues; i > 0; --i) 1506 for (int i = nvalues; i > 0; --i)
1508 { 1507 {
1509 // pop the last element of the stack, to store it in the uservalue at its proper index 1508 // pop the last element of the stack, to store it in the uservalue at its proper index
1510 lua_rawseti(L, kUsr, i); 1509 lua_rawseti(L_, kUsr, i);
1511 } 1510 }
1512 } 1511 }
1513 break; 1512 break;
@@ -1516,11 +1515,11 @@ LUAG_FUNC(thread_index)
1516 // me[-2] could carry the stack table, but even 1515 // me[-2] could carry the stack table, but even
1517 // me[-1] is rather unnecessary (and undocumented); 1516 // me[-1] is rather unnecessary (and undocumented);
1518 // use ':join()' instead. --AKa 22-Jan-2009 1517 // use ':join()' instead. --AKa 22-Jan-2009
1519 LUA_ASSERT(L, lua_isnil(L, 4) && !lua_isnil(L, 5) && lua_istable(L, 6)); 1518 LUA_ASSERT(L_, lua_isnil(L_, 4) && !lua_isnil(L_, 5) && lua_istable(L_, 6));
1520 // store errstring at key -1 1519 // store errstring at key -1
1521 lua_pushnumber(L, -1); 1520 lua_pushnumber(L_, -1);
1522 lua_pushvalue(L, 5); 1521 lua_pushvalue(L_, 5);
1523 lua_rawset(L, kUsr); 1522 lua_rawset(L_, kUsr);
1524 break; 1523 break;
1525 1524
1526 case Lane::Cancelled: 1525 case Lane::Cancelled:
@@ -1528,13 +1527,13 @@ LUAG_FUNC(thread_index)
1528 break; 1527 break;
1529 } 1528 }
1530 } 1529 }
1531 lua_settop(L, 3); // self KEY ENV 1530 lua_settop(L_, 3); // self KEY ENV
1532 int const key{ static_cast<int>(lua_tointeger(L, kKey)) }; 1531 int const key{ static_cast<int>(lua_tointeger(L_, kKey)) };
1533 if (key != -1) 1532 if (key != -1)
1534 { 1533 {
1535 lua_pushnumber(L, -1); // self KEY ENV -1 1534 lua_pushnumber(L_, -1); // self KEY ENV -1
1536 lua_rawget(L, kUsr); // self KEY ENV "error"|nil 1535 lua_rawget(L_, kUsr); // self KEY ENV "error"|nil
1537 if (!lua_isnil(L, -1)) // an error was stored 1536 if (!lua_isnil(L_, -1)) // an error was stored
1538 { 1537 {
1539 // Note: Lua 5.1 interpreter is not prepared to show 1538 // Note: Lua 5.1 interpreter is not prepared to show
1540 // non-string errors, so we use 'tostring()' here 1539 // non-string errors, so we use 'tostring()' here
@@ -1547,50 +1546,50 @@ LUAG_FUNC(thread_index)
1547 // Level 3 should show the line where 'h[x]' was read 1546 // Level 3 should show the line where 'h[x]' was read
1548 // but this only seems to work for string messages 1547 // but this only seems to work for string messages
1549 // (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009 1548 // (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009
1550 lua_getmetatable(L, kSelf); // self KEY ENV "error" mt 1549 lua_getmetatable(L_, kSelf); // self KEY ENV "error" mt
1551 lua_getfield(L, -1, "cached_error"); // self KEY ENV "error" mt error() 1550 lua_getfield(L_, -1, "cached_error"); // self KEY ENV "error" mt error()
1552 lua_getfield(L, -2, "cached_tostring"); // self KEY ENV "error" mt error() tostring() 1551 lua_getfield(L_, -2, "cached_tostring"); // self KEY ENV "error" mt error() tostring()
1553 lua_pushvalue(L, 4); // self KEY ENV "error" mt error() tostring() "error" 1552 lua_pushvalue(L_, 4); // self KEY ENV "error" mt error() tostring() "error"
1554 lua_call(L, 1, 1); // tostring( errstring) -- just in case // self KEY ENV "error" mt error() "error" 1553 lua_call(L_, 1, 1); // tostring( errstring) -- just in case // self KEY ENV "error" mt error() "error"
1555 lua_pushinteger(L, 3); // self KEY ENV "error" mt error() "error" 3 1554 lua_pushinteger(L_, 3); // self KEY ENV "error" mt error() "error" 3
1556 lua_call(L, 2, 0); // error( tostring( errstring), 3) // self KEY ENV "error" mt 1555 lua_call(L_, 2, 0); // error( tostring( errstring), 3) // self KEY ENV "error" mt
1557 } 1556 }
1558 else 1557 else
1559 { 1558 {
1560 lua_pop(L, 1); // self KEY ENV 1559 lua_pop(L_, 1); // self KEY ENV
1561 } 1560 }
1562 } 1561 }
1563 lua_rawgeti(L, kUsr, key); 1562 lua_rawgeti(L_, kUsr, key);
1564 } 1563 }
1565 return 1; 1564 return 1;
1566 } 1565 }
1567 if (lua_type(L, kKey) == LUA_TSTRING) 1566 if (lua_type(L_, kKey) == LUA_TSTRING)
1568 { 1567 {
1569 char const* const keystr{ lua_tostring(L, kKey) }; 1568 char const* const keystr{ lua_tostring(L_, kKey) };
1570 lua_settop(L, 2); // keep only our original arguments on the stack 1569 lua_settop(L_, 2); // keep only our original arguments on the stack
1571 if (strcmp( keystr, "status") == 0) 1570 if (strcmp( keystr, "status") == 0)
1572 { 1571 {
1573 lane->pushThreadStatus(L); // push the string representing the status 1572 lane->pushThreadStatus(L_); // push the string representing the status
1574 return 1; 1573 return 1;
1575 } 1574 }
1576 // return self.metatable[key] 1575 // return self.metatable[key]
1577 lua_getmetatable(L, kSelf); // self KEY mt 1576 lua_getmetatable(L_, kSelf); // self KEY mt
1578 lua_replace(L, -3); // mt KEY 1577 lua_replace(L_, -3); // mt KEY
1579 lua_rawget(L, -2); // mt value 1578 lua_rawget(L_, -2); // mt value
1580 // only "cancel" and "join" are registered as functions, any other string will raise an error 1579 // only "cancel" and "join" are registered as functions, any other string will raise an error
1581 if (!lua_iscfunction(L, -1)) 1580 if (!lua_iscfunction(L_, -1))
1582 { 1581 {
1583 raise_luaL_error(L, "can't index a lane with '%s'", keystr); 1582 raise_luaL_error(L_, "can't index a lane with '%s'", keystr);
1584 } 1583 }
1585 return 1; 1584 return 1;
1586 } 1585 }
1587 // unknown key 1586 // unknown key
1588 lua_getmetatable(L, kSelf); 1587 lua_getmetatable(L_, kSelf);
1589 lua_getfield(L, -1, "cached_error"); 1588 lua_getfield(L_, -1, "cached_error");
1590 lua_pushliteral(L, "Unknown key: "); 1589 lua_pushliteral(L_, "Unknown key: ");
1591 lua_pushvalue(L, kKey); 1590 lua_pushvalue(L_, kKey);
1592 lua_concat(L, 2); 1591 lua_concat(L_, 2);
1593 lua_call(L, 1, 0); // error( "Unknown key: " .. key) -> doesn't return 1592 lua_call(L_, 1, 0); // error( "Unknown key: " .. key) -> doesn't return
1594 return 0; 1593 return 0;
1595} 1594}
1596 1595
@@ -1601,8 +1600,8 @@ LUAG_FUNC(thread_index)
1601// Return a list of all known lanes 1600// Return a list of all known lanes
1602LUAG_FUNC(threads) 1601LUAG_FUNC(threads)
1603{ 1602{
1604 int const top{ lua_gettop(L) }; 1603 int const top{ lua_gettop(L_) };
1605 Universe* const U{ universe_get(L) }; 1604 Universe* const U{ universe_get(L_) };
1606 1605
1607 // List _all_ still running threads 1606 // List _all_ still running threads
1608 // 1607 //
@@ -1611,20 +1610,20 @@ LUAG_FUNC(threads)
1611 { 1610 {
1612 Lane* lane{ U->tracking_first }; 1611 Lane* lane{ U->tracking_first };
1613 int index = 0; 1612 int index = 0;
1614 lua_newtable(L); // {} 1613 lua_newtable(L_); // {}
1615 while (lane != TRACKING_END) 1614 while (lane != TRACKING_END)
1616 { 1615 {
1617 // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other 1616 // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other
1618 lua_newtable(L); // {} {} 1617 lua_newtable(L_); // {} {}
1619 lua_pushstring(L, lane->debug_name); // {} {} "name" 1618 lua_pushstring(L_, lane->debug_name); // {} {} "name"
1620 lua_setfield(L, -2, "name"); // {} {} 1619 lua_setfield(L_, -2, "name"); // {} {}
1621 lane->pushThreadStatus(L); // {} {} "status" 1620 lane->pushThreadStatus(L_); // {} {} "status"
1622 lua_setfield(L, -2, "status"); // {} {} 1621 lua_setfield(L_, -2, "status"); // {} {}
1623 lua_rawseti(L, -2, ++index); // {} 1622 lua_rawseti(L_, -2, ++index); // {}
1624 lane = lane->tracking_next; 1623 lane = lane->tracking_next;
1625 } 1624 }
1626 } 1625 }
1627 return lua_gettop(L) - top; // 0 or 1 1626 return lua_gettop(L_) - top; // 0 or 1
1628} 1627}
1629#endif // HAVE_LANE_TRACKING() 1628#endif // HAVE_LANE_TRACKING()
1630 1629
@@ -1643,7 +1642,7 @@ LUAG_FUNC(now_secs)
1643 auto const now{ std::chrono::system_clock::now() }; 1642 auto const now{ std::chrono::system_clock::now() };
1644 lua_Duration duration { now.time_since_epoch() }; 1643 lua_Duration duration { now.time_since_epoch() };
1645 1644
1646 lua_pushnumber(L, duration.count()); 1645 lua_pushnumber(L_, duration.count());
1647 return 1; 1646 return 1;
1648} 1647}
1649 1648
@@ -1664,8 +1663,8 @@ LUAG_FUNC(wakeup_conv)
1664 // .yday (day of the year) 1663 // .yday (day of the year)
1665 // .isdst (daylight saving on/off) 1664 // .isdst (daylight saving on/off)
1666 1665
1667 STACK_CHECK_START_REL(L, 0); 1666 STACK_CHECK_START_REL(L_, 0);
1668 auto readInteger = [L](char const* name_) 1667 auto readInteger = [L = L_](char const* name_)
1669 { 1668 {
1670 lua_getfield(L, 1, name_); 1669 lua_getfield(L, 1, name_);
1671 lua_Integer const val{ lua_tointeger(L, -1) }; 1670 lua_Integer const val{ lua_tointeger(L, -1) };
@@ -1678,15 +1677,15 @@ LUAG_FUNC(wakeup_conv)
1678 int const hour{ readInteger("hour") }; 1677 int const hour{ readInteger("hour") };
1679 int const min{ readInteger("min") }; 1678 int const min{ readInteger("min") };
1680 int const sec{ readInteger("sec") }; 1679 int const sec{ readInteger("sec") };
1681 STACK_CHECK(L, 0); 1680 STACK_CHECK(L_, 0);
1682 1681
1683 // If Lua table has '.isdst' we trust that. If it does not, we'll let 1682 // If Lua table has '.isdst' we trust that. If it does not, we'll let
1684 // 'mktime' decide on whether the time is within DST or not (value -1). 1683 // 'mktime' decide on whether the time is within DST or not (value -1).
1685 // 1684 //
1686 lua_getfield(L, 1, "isdst" ); 1685 lua_getfield(L_, 1, "isdst" );
1687 int const isdst{ lua_isboolean(L, -1) ? lua_toboolean(L, -1) : -1 }; 1686 int const isdst{ lua_isboolean(L_, -1) ? lua_toboolean(L_, -1) : -1 };
1688 lua_pop(L,1); 1687 lua_pop(L_,1);
1689 STACK_CHECK(L, 0); 1688 STACK_CHECK(L_, 0);
1690 1689
1691 std::tm t{}; 1690 std::tm t{};
1692 t.tm_year = year - 1900; 1691 t.tm_year = year - 1900;
@@ -1697,7 +1696,7 @@ LUAG_FUNC(wakeup_conv)
1697 t.tm_sec= sec; // 0..60 1696 t.tm_sec= sec; // 0..60
1698 t.tm_isdst= isdst; // 0/1/negative 1697 t.tm_isdst= isdst; // 0/1/negative
1699 1698
1700 lua_pushnumber(L, static_cast<lua_Number>(std::mktime(&t))); // resolution: 1 second 1699 lua_pushnumber(L_, static_cast<lua_Number>(std::mktime(&t))); // resolution: 1 second
1701 return 1; 1700 return 1;
1702} 1701}
1703 1702
@@ -1705,7 +1704,7 @@ LUAG_FUNC(wakeup_conv)
1705// ######################################## Module linkage ######################################### 1704// ######################################## Module linkage #########################################
1706// ################################################################################################# 1705// #################################################################################################
1707 1706
1708extern int LG_linda(lua_State* L); 1707extern int LG_linda(lua_State* L_);
1709static struct luaL_Reg const lanes_functions[] = 1708static struct luaL_Reg const lanes_functions[] =
1710{ 1709{
1711 { "linda", LG_linda }, 1710 { "linda", LG_linda },
@@ -1740,148 +1739,148 @@ LUAG_FUNC(configure)
1740 ); 1739 );
1741 } 1740 }
1742 1741
1743 Universe* U = universe_get(L); 1742 Universe* U = universe_get(L_);
1744 bool const from_master_state{ U == nullptr }; 1743 bool const from_master_state{ U == nullptr };
1745 char const* name = luaL_checkstring(L, lua_upvalueindex(1)); 1744 char const* name = luaL_checkstring(L_, lua_upvalueindex(1));
1746 LUA_ASSERT(L, lua_type(L, 1) == LUA_TTABLE); 1745 LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE);
1747 1746
1748 STACK_GROW(L, 4); 1747 STACK_GROW(L_, 4);
1749 STACK_CHECK_START_ABS(L, 1); // settings 1748 STACK_CHECK_START_ABS(L_, 1); // settings
1750 1749
1751 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); 1750 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L));
1752 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 1751 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
1753 1752
1754 if (U == nullptr) 1753 if (U == nullptr)
1755 { 1754 {
1756 U = universe_create(L); // settings universe 1755 U = universe_create(L_); // settings universe
1757 DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U }); 1756 DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U });
1758 lua_newtable( L); // settings universe mt 1757 lua_newtable(L_); // settings universe mt
1759 lua_getfield(L, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout 1758 lua_getfield(L_, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout
1760 lua_getfield(L, 1, "shutdown_mode"); // settings universe mt shutdown_timeout shutdown_mode 1759 lua_getfield(L_, 1, "shutdown_mode"); // settings universe mt shutdown_timeout shutdown_mode
1761 lua_pushcclosure(L, universe_gc, 2); // settings universe mt universe_gc 1760 lua_pushcclosure(L_, universe_gc, 2); // settings universe mt universe_gc
1762 lua_setfield(L, -2, "__gc"); // settings universe mt 1761 lua_setfield(L_, -2, "__gc"); // settings universe mt
1763 lua_setmetatable(L, -2); // settings universe 1762 lua_setmetatable(L_, -2); // settings universe
1764 lua_pop(L, 1); // settings 1763 lua_pop(L_, 1); // settings
1765 lua_getfield(L, 1, "verbose_errors"); // settings verbose_errors 1764 lua_getfield(L_, 1, "verbose_errors"); // settings verbose_errors
1766 U->verboseErrors = lua_toboolean(L, -1) ? true : false; 1765 U->verboseErrors = lua_toboolean(L_, -1) ? true : false;
1767 lua_pop(L, 1); // settings 1766 lua_pop(L_, 1); // settings
1768 lua_getfield(L, 1, "demote_full_userdata"); // settings demote_full_userdata 1767 lua_getfield(L_, 1, "demote_full_userdata"); // settings demote_full_userdata
1769 U->demoteFullUserdata = lua_toboolean(L, -1) ? true : false; 1768 U->demoteFullUserdata = lua_toboolean(L_, -1) ? true : false;
1770 lua_pop(L, 1); // settings 1769 lua_pop(L_, 1); // settings
1771#if HAVE_LANE_TRACKING() 1770#if HAVE_LANE_TRACKING()
1772 lua_getfield(L, 1, "track_lanes"); // settings track_lanes 1771 lua_getfield(L_, 1, "track_lanes"); // settings track_lanes
1773 U->tracking_first = lua_toboolean(L, -1) ? TRACKING_END : nullptr; 1772 U->tracking_first = lua_toboolean(L_, -1) ? TRACKING_END : nullptr;
1774 lua_pop(L, 1); // settings 1773 lua_pop(L_, 1); // settings
1775#endif // HAVE_LANE_TRACKING() 1774#endif // HAVE_LANE_TRACKING()
1776 // Linked chains handling 1775 // Linked chains handling
1777 U->selfdestruct_first = SELFDESTRUCT_END; 1776 U->selfdestruct_first = SELFDESTRUCT_END;
1778 initialize_allocator_function( U, L); 1777 initialize_allocator_function( U, L_);
1779 initialize_on_state_create( U, L); 1778 initialize_on_state_create( U, L_);
1780 init_keepers( U, L); 1779 init_keepers( U, L_);
1781 STACK_CHECK(L, 1); 1780 STACK_CHECK(L_, 1);
1782 1781
1783 // Initialize 'timer_deep'; a common Linda object shared by all states 1782 // Initialize 'timer_deep'; a common Linda object shared by all states
1784 lua_pushcfunction(L, LG_linda); // settings lanes.linda 1783 lua_pushcfunction(L_, LG_linda); // settings lanes.linda
1785 lua_pushliteral(L, "lanes-timer"); // settings lanes.linda "lanes-timer" 1784 lua_pushliteral(L_, "lanes-timer"); // settings lanes.linda "lanes-timer"
1786 lua_call(L, 1, 1); // settings linda 1785 lua_call(L_, 1, 1); // settings linda
1787 STACK_CHECK(L, 2); 1786 STACK_CHECK(L_, 2);
1788 1787
1789 // Proxy userdata contents is only a 'DeepPrelude*' pointer 1788 // Proxy userdata contents is only a 'DeepPrelude*' pointer
1790 U->timer_deep = *lua_tofulluserdata<DeepPrelude*>(L, -1); 1789 U->timer_deep = *lua_tofulluserdata<DeepPrelude*>(L_, -1);
1791 // increment refcount so that this linda remains alive as long as the universe exists. 1790 // increment refcount so that this linda remains alive as long as the universe exists.
1792 U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); 1791 U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed);
1793 lua_pop(L, 1); // settings 1792 lua_pop(L_, 1); // settings
1794 } 1793 }
1795 STACK_CHECK(L, 1); 1794 STACK_CHECK(L_, 1);
1796 1795
1797 // Serialize calls to 'require' from now on, also in the primary state 1796 // Serialize calls to 'require' from now on, also in the primary state
1798 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); 1797 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L_);
1799 1798
1800 // Retrieve main module interface table 1799 // Retrieve main module interface table
1801 lua_pushvalue(L, lua_upvalueindex( 2)); // settings M 1800 lua_pushvalue(L_, lua_upvalueindex( 2)); // settings M
1802 // remove configure() (this function) from the module interface 1801 // remove configure() (this function) from the module interface
1803 lua_pushnil( L); // settings M nil 1802 lua_pushnil( L_); // settings M nil
1804 lua_setfield(L, -2, "configure"); // settings M 1803 lua_setfield(L_, -2, "configure"); // settings M
1805 // add functions to the module's table 1804 // add functions to the module's table
1806 luaG_registerlibfuncs(L, lanes_functions); 1805 luaG_registerlibfuncs(L_, lanes_functions);
1807#if HAVE_LANE_TRACKING() 1806#if HAVE_LANE_TRACKING()
1808 // register core.threads() only if settings say it should be available 1807 // register core.threads() only if settings say it should be available
1809 if (U->tracking_first != nullptr) 1808 if (U->tracking_first != nullptr)
1810 { 1809 {
1811 lua_pushcfunction(L, LG_threads); // settings M LG_threads() 1810 lua_pushcfunction(L_, LG_threads); // settings M LG_threads()
1812 lua_setfield(L, -2, "threads"); // settings M 1811 lua_setfield(L_, -2, "threads"); // settings M
1813 } 1812 }
1814#endif // HAVE_LANE_TRACKING() 1813#endif // HAVE_LANE_TRACKING()
1815 STACK_CHECK(L, 2); 1814 STACK_CHECK(L_, 2);
1816 1815
1817 { 1816 {
1818 char const* errmsg{ DeepFactory::PushDeepProxy(DestState{ L }, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep 1817 char const* errmsg{ DeepFactory::PushDeepProxy(DestState{ L_ }, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep
1819 if (errmsg != nullptr) 1818 if (errmsg != nullptr)
1820 { 1819 {
1821 raise_luaL_error(L, errmsg); 1820 raise_luaL_error(L_, errmsg);
1822 } 1821 }
1823 lua_setfield(L, -2, "timer_gateway"); // settings M 1822 lua_setfield(L_, -2, "timer_gateway"); // settings M
1824 } 1823 }
1825 STACK_CHECK(L, 2); 1824 STACK_CHECK(L_, 2);
1826 1825
1827 // prepare the metatable for threads 1826 // prepare the metatable for threads
1828 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } 1827 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname }
1829 // 1828 //
1830 if (luaL_newmetatable(L, "Lane")) // settings M mt 1829 if (luaL_newmetatable(L_, "Lane")) // settings M mt
1831 { 1830 {
1832 lua_pushcfunction(L, lane_gc); // settings M mt lane_gc 1831 lua_pushcfunction(L_, lane_gc); // settings M mt lane_gc
1833 lua_setfield(L, -2, "__gc"); // settings M mt 1832 lua_setfield(L_, -2, "__gc"); // settings M mt
1834 lua_pushcfunction(L, LG_thread_index); // settings M mt LG_thread_index 1833 lua_pushcfunction(L_, LG_thread_index); // settings M mt LG_thread_index
1835 lua_setfield(L, -2, "__index"); // settings M mt 1834 lua_setfield(L_, -2, "__index"); // settings M mt
1836 lua_getglobal(L, "error"); // settings M mt error 1835 lua_getglobal(L_, "error"); // settings M mt error
1837 LUA_ASSERT(L, lua_isfunction(L, -1)); 1836 LUA_ASSERT(L_, lua_isfunction(L_, -1));
1838 lua_setfield(L, -2, "cached_error"); // settings M mt 1837 lua_setfield(L_, -2, "cached_error"); // settings M mt
1839 lua_getglobal(L, "tostring"); // settings M mt tostring 1838 lua_getglobal(L_, "tostring"); // settings M mt tostring
1840 LUA_ASSERT(L, lua_isfunction(L, -1)); 1839 LUA_ASSERT(L_, lua_isfunction(L_, -1));
1841 lua_setfield(L, -2, "cached_tostring"); // settings M mt 1840 lua_setfield(L_, -2, "cached_tostring"); // settings M mt
1842 lua_pushcfunction(L, LG_thread_join); // settings M mt LG_thread_join 1841 lua_pushcfunction(L_, LG_thread_join); // settings M mt LG_thread_join
1843 lua_setfield(L, -2, "join"); // settings M mt 1842 lua_setfield(L_, -2, "join"); // settings M mt
1844 lua_pushcfunction(L, LG_get_debug_threadname); // settings M mt LG_get_debug_threadname 1843 lua_pushcfunction(L_, LG_get_debug_threadname); // settings M mt LG_get_debug_threadname
1845 lua_setfield(L, -2, "get_debug_threadname"); // settings M mt 1844 lua_setfield(L_, -2, "get_debug_threadname"); // settings M mt
1846 lua_pushcfunction(L, LG_thread_cancel); // settings M mt LG_thread_cancel 1845 lua_pushcfunction(L_, LG_thread_cancel); // settings M mt LG_thread_cancel
1847 lua_setfield(L, -2, "cancel"); // settings M mt 1846 lua_setfield(L_, -2, "cancel"); // settings M mt
1848 lua_pushliteral(L, "Lane"); // settings M mt "Lane" 1847 lua_pushliteral(L_, "Lane"); // settings M mt "Lane"
1849 lua_setfield(L, -2, "__metatable"); // settings M mt 1848 lua_setfield(L_, -2, "__metatable"); // settings M mt
1850 } 1849 }
1851 1850
1852 lua_pushcclosure(L, LG_lane_new, 1); // settings M lane_new 1851 lua_pushcclosure(L_, LG_lane_new, 1); // settings M lane_new
1853 lua_setfield(L, -2, "lane_new"); // settings M 1852 lua_setfield(L_, -2, "lane_new"); // settings M
1854 1853
1855 // we can't register 'lanes.require' normally because we want to create an upvalued closure 1854 // we can't register 'lanes.require' normally because we want to create an upvalued closure
1856 lua_getglobal(L, "require"); // settings M require 1855 lua_getglobal(L_, "require"); // settings M require
1857 lua_pushcclosure(L, LG_require, 1); // settings M lanes.require 1856 lua_pushcclosure(L_, LG_require, 1); // settings M lanes.require
1858 lua_setfield(L, -2, "require"); // settings M 1857 lua_setfield(L_, -2, "require"); // settings M
1859 1858
1860 lua_pushfstring( 1859 lua_pushfstring(
1861 L, "%d.%d.%d" 1860 L_, "%d.%d.%d"
1862 , LANES_VERSION_MAJOR, LANES_VERSION_MINOR, LANES_VERSION_PATCH 1861 , LANES_VERSION_MAJOR, LANES_VERSION_MINOR, LANES_VERSION_PATCH
1863 ); // settings M VERSION 1862 ); // settings M VERSION
1864 lua_setfield(L, -2, "version"); // settings M 1863 lua_setfield(L_, -2, "version"); // settings M
1865 1864
1866 lua_pushinteger(L, kThreadPrioMax); // settings M kThreadPrioMax 1865 lua_pushinteger(L_, kThreadPrioMax); // settings M kThreadPrioMax
1867 lua_setfield(L, -2, "max_prio"); // settings M 1866 lua_setfield(L_, -2, "max_prio"); // settings M
1868 1867
1869 kCancelError.pushKey(L); // settings M kCancelError 1868 kCancelError.pushKey(L_); // settings M kCancelError
1870 lua_setfield(L, -2, "cancel_error"); // settings M 1869 lua_setfield(L_, -2, "cancel_error"); // settings M
1871 1870
1872 kNilSentinel.pushKey(L); // settings M kNilSentinel 1871 kNilSentinel.pushKey(L_); // settings M kNilSentinel
1873 lua_setfield(L, -2, "null"); // settings M 1872 lua_setfield(L_, -2, "null"); // settings M
1874 1873
1875 STACK_CHECK(L, 2); // reference stack contains only the function argument 'settings' 1874 STACK_CHECK(L_, 2); // reference stack contains only the function argument 'settings'
1876 // we'll need this every time we transfer some C function from/to this state 1875 // we'll need this every time we transfer some C function from/to this state
1877 kLookupRegKey.setValue(L, [](lua_State* L) { lua_newtable(L); }); // settings M 1876 kLookupRegKey.setValue(L_, [](lua_State* L_) { lua_newtable(L_); }); // settings M
1878 STACK_CHECK(L, 2); 1877 STACK_CHECK(L_, 2);
1879 1878
1880 // register all native functions found in that module in the transferable functions database 1879 // register all native functions found in that module in the transferable functions database
1881 // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) 1880 // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names)
1882 // for example in package.loaded["lanes.core"].* 1881 // for example in package.loaded["lanes.core"].*
1883 populate_func_lookup_table(L, -1, name); 1882 populate_func_lookup_table(L_, -1, name);
1884 STACK_CHECK(L, 2); 1883 STACK_CHECK(L_, 2);
1885 1884
1886 // record all existing C/JIT-fast functions 1885 // record all existing C/JIT-fast functions
1887 // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack 1886 // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
@@ -1890,15 +1889,15 @@ LUAG_FUNC(configure)
1890 // don't do this when called during the initialization of a new lane, 1889 // don't do this when called during the initialization of a new lane,
1891 // because we will do it after on_state_create() is called, 1890 // because we will do it after on_state_create() is called,
1892 // and we don't want to skip _G because of caching in case globals are created then 1891 // and we don't want to skip _G because of caching in case globals are created then
1893 lua_pushglobaltable( L); // settings M _G 1892 lua_pushglobaltable(L_); // settings M _G
1894 populate_func_lookup_table(L, -1, nullptr); 1893 populate_func_lookup_table(L_, -1, nullptr);
1895 lua_pop(L, 1); // settings M 1894 lua_pop(L_, 1); // settings M
1896 } 1895 }
1897 lua_pop(L, 1); // settings 1896 lua_pop(L_, 1); // settings
1898 1897
1899 // set _R[kConfigRegKey] = settings 1898 // set _R[kConfigRegKey] = settings
1900 kConfigRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 1899 kConfigRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); });
1901 STACK_CHECK(L, 1); 1900 STACK_CHECK(L_, 1);
1902 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); 1901 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L));
1903 // Return the settings table 1902 // Return the settings table
1904 return 1; 1903 return 1;
@@ -1962,70 +1961,70 @@ static void EnableCrashingOnCrashes(void)
1962} 1961}
1963#endif // PLATFORM_WIN32 && !defined NDEBUG 1962#endif // PLATFORM_WIN32 && !defined NDEBUG
1964 1963
1965LANES_API int luaopen_lanes_core( lua_State* L) 1964LANES_API int luaopen_lanes_core( lua_State* L_)
1966{ 1965{
1967#if defined PLATFORM_WIN32 && !defined NDEBUG 1966#if defined PLATFORM_WIN32 && !defined NDEBUG
1968 EnableCrashingOnCrashes(); 1967 EnableCrashingOnCrashes();
1969#endif // defined PLATFORM_WIN32 && !defined NDEBUG 1968#endif // defined PLATFORM_WIN32 && !defined NDEBUG
1970 1969
1971 STACK_GROW(L, 4); 1970 STACK_GROW(L_, 4);
1972 STACK_CHECK_START_REL(L, 0); 1971 STACK_CHECK_START_REL(L_, 0);
1973 1972
1974 // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too 1973 // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too
1975 lua_getglobal(L, "jit"); // {jit?} 1974 lua_getglobal(L_, "jit"); // {jit?}
1976#if LUAJIT_FLAVOR() == 0 1975#if LUAJIT_FLAVOR() == 0
1977 if (!lua_isnil(L, -1)) 1976 if (!lua_isnil(L_, -1))
1978 raise_luaL_error(L, "Lanes is built for PUC-Lua, don't run from LuaJIT"); 1977 raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT");
1979#else 1978#else
1980 if (lua_isnil(L, -1)) 1979 if (lua_isnil(L_, -1))
1981 raise_luaL_error(L, "Lanes is built for LuaJIT, don't run from PUC-Lua"); 1980 raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua");
1982#endif 1981#endif
1983 lua_pop(L, 1); // 1982 lua_pop(L_, 1); //
1984 STACK_CHECK(L, 0); 1983 STACK_CHECK(L_, 0);
1985 1984
1986 // Create main module interface table 1985 // Create main module interface table
1987 // we only have 1 closure, which must be called to configure Lanes 1986 // we only have 1 closure, which must be called to configure Lanes
1988 lua_newtable(L); // M 1987 lua_newtable(L_); // M
1989 lua_pushvalue(L, 1); // M "lanes.core" 1988 lua_pushvalue(L_, 1); // M "lanes.core"
1990 lua_pushvalue(L, -2); // M "lanes.core" M 1989 lua_pushvalue(L_, -2); // M "lanes.core" M
1991 lua_pushcclosure(L, LG_configure, 2); // M LG_configure() 1990 lua_pushcclosure(L_, LG_configure, 2); // M LG_configure()
1992 kConfigRegKey.pushValue(L); // M LG_configure() settings 1991 kConfigRegKey.pushValue(L_); // M LG_configure() settings
1993 if (!lua_isnil(L, -1)) // this is not the first require "lanes.core": call configure() immediately 1992 if (!lua_isnil(L_, -1)) // this is not the first require "lanes.core": call configure() immediately
1994 { 1993 {
1995 lua_pushvalue(L, -1); // M LG_configure() settings settings 1994 lua_pushvalue(L_, -1); // M LG_configure() settings settings
1996 lua_setfield(L, -4, "settings"); // M LG_configure() settings 1995 lua_setfield(L_, -4, "settings"); // M LG_configure() settings
1997 lua_call(L, 1, 0); // M 1996 lua_call(L_, 1, 0); // M
1998 } 1997 }
1999 else 1998 else
2000 { 1999 {
2001 // will do nothing on first invocation, as we haven't stored settings in the registry yet 2000 // will do nothing on first invocation, as we haven't stored settings in the registry yet
2002 lua_setfield(L, -3, "settings"); // M LG_configure() 2001 lua_setfield(L_, -3, "settings"); // M LG_configure()
2003 lua_setfield(L, -2, "configure"); // M 2002 lua_setfield(L_, -2, "configure"); // M
2004 } 2003 }
2005 2004
2006 STACK_CHECK(L, 1); 2005 STACK_CHECK(L_, 1);
2007 return 1; 2006 return 1;
2008} 2007}
2009 2008
2010[[nodiscard]] static int default_luaopen_lanes(lua_State* L) 2009[[nodiscard]] static int default_luaopen_lanes(lua_State* L_)
2011{ 2010{
2012 int const rc{ luaL_loadfile(L, "lanes.lua") || lua_pcall(L, 0, 1, 0) }; 2011 int const rc{ luaL_loadfile(L_, "lanes.lua") || lua_pcall(L_, 0, 1, 0) };
2013 if (rc != LUA_OK) 2012 if (rc != LUA_OK)
2014 { 2013 {
2015 raise_luaL_error(L, "failed to initialize embedded Lanes"); 2014 raise_luaL_error(L_, "failed to initialize embedded Lanes");
2016 } 2015 }
2017 return 1; 2016 return 1;
2018} 2017}
2019 2018
2020// call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application 2019// call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application
2021LANES_API void luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) 2020LANES_API void luaopen_lanes_embedded( lua_State* L_, lua_CFunction _luaopen_lanes)
2022{ 2021{
2023 STACK_CHECK_START_REL(L, 0); 2022 STACK_CHECK_START_REL(L_, 0);
2024 // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded 2023 // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded
2025 luaL_requiref(L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core 2024 luaL_requiref(L_, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core
2026 lua_pop(L, 1); // ... 2025 lua_pop(L_, 1); // ...
2027 STACK_CHECK(L, 0); 2026 STACK_CHECK(L_, 0);
2028 // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it 2027 // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it
2029 luaL_requiref(L, "lanes", _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // ... lanes 2028 luaL_requiref(L_, "lanes", _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // ... lanes
2030 STACK_CHECK(L, 1); 2029 STACK_CHECK(L_, 1);
2031} 2030}
diff --git a/src/lanes.h b/src/lanes.h
index 287e405..6fea869 100644
--- a/src/lanes.h
+++ b/src/lanes.h
@@ -23,9 +23,9 @@ extern "C"
23#define LANES_VERSION_GREATER_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH > PATCH)))) 23#define LANES_VERSION_GREATER_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH > PATCH))))
24#define LANES_VERSION_GREATER_OR_EQUAL(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH >= PATCH)))) 24#define LANES_VERSION_GREATER_OR_EQUAL(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH >= PATCH))))
25 25
26LANES_API [[nodiscard]] int luaopen_lanes_core(lua_State* L); 26LANES_API [[nodiscard]] int luaopen_lanes_core(lua_State* L_);
27 27
28// Call this to work with embedded Lanes instead of calling luaopen_lanes_core() 28// Call this to work with embedded Lanes instead of calling luaopen_lanes_core()
29LANES_API void luaopen_lanes_embedded(lua_State* L, lua_CFunction _luaopen_lanes); 29LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction _luaopen_lanes);
30using luaopen_lanes_embedded_t = void (*)(lua_State* L, lua_CFunction luaopen_lanes_); 30using luaopen_lanes_embedded_t = void (*)(lua_State* L_, lua_CFunction luaopen_lanes_);
31static_assert(std::is_same_v<decltype(&luaopen_lanes_embedded), luaopen_lanes_embedded_t>, "signature changed: check all uses of luaopen_lanes_embedded_t"); 31static_assert(std::is_same_v<decltype(&luaopen_lanes_embedded), luaopen_lanes_embedded_t>, "signature changed: check all uses of luaopen_lanes_embedded_t");
diff --git a/src/lanes_private.h b/src/lanes_private.h
index 859c8a2..083ac4e 100644
--- a/src/lanes_private.h
+++ b/src/lanes_private.h
@@ -98,7 +98,7 @@ static constexpr RegistryUniqueKey kLanePointerRegKey{ 0x2D8CF03FE9F0A51Aull };
98// 'Lane' are malloc/free'd and the handle only carries a pointer. 98// 'Lane' are malloc/free'd and the handle only carries a pointer.
99// This is not deep userdata since the handle's not portable among lanes. 99// This is not deep userdata since the handle's not portable among lanes.
100// 100//
101[[nodiscard]] inline Lane* ToLane(lua_State* L, int i_) 101[[nodiscard]] inline Lane* ToLane(lua_State* L_, int i_)
102{ 102{
103 return *(static_cast<Lane**>(luaL_checkudata(L, i_, "Lane"))); 103 return *(static_cast<Lane**>(luaL_checkudata(L_, i_, "Lane")));
104} 104}
diff --git a/src/linda.cpp b/src/linda.cpp
index 67a97c2..f88158a 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -127,11 +127,11 @@ template <bool OPT>
127 127
128// ################################################################################################# 128// #################################################################################################
129 129
130static void check_key_types(lua_State* L, int start_, int end_) 130static void check_key_types(lua_State* L_, int start_, int end_)
131{ 131{
132 for (int i{ start_ }; i <= end_; ++i) 132 for (int i{ start_ }; i <= end_; ++i)
133 { 133 {
134 LuaType const t{ lua_type_as_enum(L, i) }; 134 LuaType const t{ lua_type_as_enum(L_, i) };
135 switch (t) 135 switch (t)
136 { 136 {
137 case LuaType::BOOLEAN: 137 case LuaType::BOOLEAN:
@@ -144,25 +144,25 @@ static void check_key_types(lua_State* L, int start_, int end_)
144 static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; 144 static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel };
145 for (UniqueKey const& key : kKeysToCheck) 145 for (UniqueKey const& key : kKeysToCheck)
146 { 146 {
147 if (key.equals(L, i)) 147 if (key.equals(L_, i))
148 { 148 {
149 raise_luaL_error(L, "argument #%d: can't use %s as a key", i, key.m_debugName); 149 raise_luaL_error(L_, "argument #%d: can't use %s as a key", i, key.m_debugName);
150 break; 150 break;
151 } 151 }
152 } 152 }
153 } 153 }
154 break; 154 break;
155 } 155 }
156 raise_luaL_error(L, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); 156 raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i);
157 } 157 }
158} 158}
159 159
160// ################################################################################################# 160// #################################################################################################
161 161
162// used to perform all linda operations that access keepers 162// used to perform all linda operations that access keepers
163int Linda::ProtectedCall(lua_State* L, lua_CFunction f_) 163int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_)
164{ 164{
165 Linda* const linda{ ToLinda<false>(L, 1) }; 165 Linda* const linda{ ToLinda<false>(L_, 1) };
166 166
167 // acquire the keeper 167 // acquire the keeper
168 Keeper* const K{ linda->acquireKeeper() }; 168 Keeper* const K{ linda->acquireKeeper() };
@@ -170,13 +170,13 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_)
170 if (KL == nullptr) 170 if (KL == nullptr)
171 return 0; 171 return 0;
172 // if we didn't do anything wrong, the keeper stack should be clean 172 // if we didn't do anything wrong, the keeper stack should be clean
173 LUA_ASSERT(L, lua_gettop(KL) == 0); 173 LUA_ASSERT(L_, lua_gettop(KL) == 0);
174 174
175 // push the function to be called and move it before the arguments 175 // push the function to be called and move it before the arguments
176 lua_pushcfunction(L, f_); 176 lua_pushcfunction(L_, f_);
177 lua_insert(L, 1); 177 lua_insert(L_, 1);
178 // do a protected call 178 // do a protected call
179 int const rc{ lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) }; 179 int const rc{ lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0) };
180 // whatever happens, the keeper state stack must be empty when we are done 180 // whatever happens, the keeper state stack must be empty when we are done
181 lua_settop(KL, 0); 181 lua_settop(KL, 0);
182 182
@@ -186,10 +186,10 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_)
186 // if there was an error, forward it 186 // if there was an error, forward it
187 if (rc != LUA_OK) 187 if (rc != LUA_OK)
188 { 188 {
189 raise_lua_error(L); 189 raise_lua_error(L_);
190 } 190 }
191 // return whatever the actual operation provided 191 // return whatever the actual operation provided
192 return lua_gettop(L); 192 return lua_gettop(L_);
193} 193}
194 194
195// ################################################################################################# 195// #################################################################################################
@@ -205,27 +205,27 @@ int Linda::ProtectedCall(lua_State* L, lua_CFunction f_)
205*/ 205*/
206LUAG_FUNC(linda_send) 206LUAG_FUNC(linda_send)
207{ 207{
208 auto send = [](lua_State* L) 208 auto send = [](lua_State* L_)
209 { 209 {
210 Linda* const linda{ ToLinda<false>(L, 1) }; 210 Linda* const linda{ ToLinda<false>(L_, 1) };
211 std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; 211 std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() };
212 int key_i{ 2 }; // index of first key, if timeout not there 212 int key_i{ 2 }; // index of first key, if timeout not there
213 213
214 if (lua_type(L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion 214 if (lua_type(L_, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion
215 { 215 {
216 lua_Duration const duration{ lua_tonumber(L, 2) }; 216 lua_Duration const duration{ lua_tonumber(L_, 2) };
217 if (duration.count() >= 0.0) 217 if (duration.count() >= 0.0)
218 { 218 {
219 until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); 219 until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration);
220 } 220 }
221 ++key_i; 221 ++key_i;
222 } 222 }
223 else if (lua_isnil(L, 2)) // alternate explicit "infinite timeout" by passing nil before the key 223 else if (lua_isnil(L_, 2)) // alternate explicit "infinite timeout" by passing nil before the key
224 { 224 {
225 ++key_i; 225 ++key_i;
226 } 226 }
227 227
228 bool const as_nil_sentinel{ kNilSentinel.equals(L, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided 228 bool const as_nil_sentinel{ kNilSentinel.equals(L_, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided
229 if (as_nil_sentinel) 229 if (as_nil_sentinel)
230 { 230 {
231 // the real key to send data to is after the kNilSentinel marker 231 // the real key to send data to is after the kNilSentinel marker
@@ -233,31 +233,31 @@ LUAG_FUNC(linda_send)
233 } 233 }
234 234
235 // make sure the key is of a valid type 235 // make sure the key is of a valid type
236 check_key_types(L, key_i, key_i); 236 check_key_types(L_, key_i, key_i);
237 237
238 STACK_GROW(L, 1); 238 STACK_GROW(L_, 1);
239 239
240 // make sure there is something to send 240 // make sure there is something to send
241 if (lua_gettop(L) == key_i) 241 if (lua_gettop(L_) == key_i)
242 { 242 {
243 if (as_nil_sentinel) 243 if (as_nil_sentinel)
244 { 244 {
245 // send a single nil if nothing is provided 245 // send a single nil if nothing is provided
246 kNilSentinel.pushKey(L); 246 kNilSentinel.pushKey(L_);
247 } 247 }
248 else 248 else
249 { 249 {
250 raise_luaL_error(L, "no data to send"); 250 raise_luaL_error(L_, "no data to send");
251 } 251 }
252 } 252 }
253 253
254 // convert nils to some special non-nil sentinel in sent values 254 // convert nils to some special non-nil sentinel in sent values
255 keeper_toggle_nil_sentinels(L, key_i + 1, LookupMode::ToKeeper); 255 keeper_toggle_nil_sentinels(L_, key_i + 1, LookupMode::ToKeeper);
256 bool ret{ false }; 256 bool ret{ false };
257 CancelRequest cancel{ CancelRequest::None }; 257 CancelRequest cancel{ CancelRequest::None };
258 KeeperCallResult pushed; 258 KeeperCallResult pushed;
259 { 259 {
260 Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L) }; 260 Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) };
261 Keeper* const K{ linda->whichKeeper() }; 261 Keeper* const K{ linda->whichKeeper() };
262 KeeperState const KL{ K ? K->L : nullptr }; 262 KeeperState const KL{ K ? K->L : nullptr };
263 if (KL == nullptr) 263 if (KL == nullptr)
@@ -279,15 +279,15 @@ LUAG_FUNC(linda_send)
279 } 279 }
280 280
281 STACK_CHECK(KL, 0); 281 STACK_CHECK(KL, 0);
282 pushed = keeper_call(linda->U, KL, KEEPER_API(send), L, linda, key_i); 282 pushed = keeper_call(linda->U, KL, KEEPER_API(send), L_, linda, key_i);
283 if (!pushed.has_value()) 283 if (!pushed.has_value())
284 { 284 {
285 break; 285 break;
286 } 286 }
287 LUA_ASSERT(L, pushed.value() == 1); 287 LUA_ASSERT(L_, pushed.value() == 1);
288 288
289 ret = lua_toboolean(L, -1) ? true : false; 289 ret = lua_toboolean(L_, -1) ? true : false;
290 lua_pop(L, 1); 290 lua_pop(L_, 1);
291 291
292 if (ret) 292 if (ret)
293 { 293 {
@@ -309,9 +309,9 @@ LUAG_FUNC(linda_send)
309 { 309 {
310 // change status of lane to "waiting" 310 // change status of lane to "waiting"
311 prev_status = lane->m_status; // Running, most likely 311 prev_status = lane->m_status; // Running, most likely
312 LUA_ASSERT(L, prev_status == Lane::Running); // but check, just in case 312 LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case
313 lane->m_status = Lane::Waiting; 313 lane->m_status = Lane::Waiting;
314 LUA_ASSERT(L, lane->m_waiting_on == nullptr); 314 LUA_ASSERT(L_, lane->m_waiting_on == nullptr);
315 lane->m_waiting_on = &linda->m_read_happened; 315 lane->m_waiting_on = &linda->m_read_happened;
316 } 316 }
317 // could not send because no room: wait until some data was read before trying again, or until timeout is reached 317 // could not send because no room: wait until some data was read before trying again, or until timeout is reached
@@ -331,26 +331,26 @@ LUAG_FUNC(linda_send)
331 331
332 if (!pushed.has_value()) 332 if (!pushed.has_value())
333 { 333 {
334 raise_luaL_error(L, "tried to copy unsupported types"); 334 raise_luaL_error(L_, "tried to copy unsupported types");
335 } 335 }
336 336
337 switch (cancel) 337 switch (cancel)
338 { 338 {
339 case CancelRequest::Soft: 339 case CancelRequest::Soft:
340 // if user wants to soft-cancel, the call returns lanes.cancel_error 340 // if user wants to soft-cancel, the call returns lanes.cancel_error
341 kCancelError.pushKey(L); 341 kCancelError.pushKey(L_);
342 return 1; 342 return 1;
343 343
344 case CancelRequest::Hard: 344 case CancelRequest::Hard:
345 // raise an error interrupting execution only in case of hard cancel 345 // raise an error interrupting execution only in case of hard cancel
346 raise_cancel_error(L); // raises an error and doesn't return 346 raise_cancel_error(L_); // raises an error and doesn't return
347 347
348 default: 348 default:
349 lua_pushboolean(L, ret); // true (success) or false (timeout) 349 lua_pushboolean(L_, ret); // true (success) or false (timeout)
350 return 1; 350 return 1;
351 } 351 }
352 }; 352 };
353 return Linda::ProtectedCall(L, send); 353 return Linda::ProtectedCall(L_, send);
354} 354}
355 355
356// ################################################################################################# 356// #################################################################################################
@@ -368,22 +368,22 @@ LUAG_FUNC(linda_send)
368 */ 368 */
369LUAG_FUNC(linda_receive) 369LUAG_FUNC(linda_receive)
370{ 370{
371 auto receive = [](lua_State* L) 371 auto receive = [](lua_State* L_)
372 { 372 {
373 Linda* const linda{ ToLinda<false>(L, 1) }; 373 Linda* const linda{ ToLinda<false>(L_, 1) };
374 std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; 374 std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() };
375 int key_i{ 2 }; // index of first key, if timeout not there 375 int key_i{ 2 }; // index of first key, if timeout not there
376 376
377 if (lua_type(L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion 377 if (lua_type(L_, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion
378 { 378 {
379 lua_Duration const duration{ lua_tonumber(L, 2) }; 379 lua_Duration const duration{ lua_tonumber(L_, 2) };
380 if (duration.count() >= 0.0) 380 if (duration.count() >= 0.0)
381 { 381 {
382 until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); 382 until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration);
383 } 383 }
384 ++key_i; 384 ++key_i;
385 } 385 }
386 else if (lua_isnil(L, 2)) // alternate explicit "infinite timeout" by passing nil before the key 386 else if (lua_isnil(L_, 2)) // alternate explicit "infinite timeout" by passing nil before the key
387 { 387 {
388 ++key_i; 388 ++key_i;
389 } 389 }
@@ -391,39 +391,39 @@ LUAG_FUNC(linda_receive)
391 keeper_api_t selected_keeper_receive{ nullptr }; 391 keeper_api_t selected_keeper_receive{ nullptr };
392 int expected_pushed_min{ 0 }, expected_pushed_max{ 0 }; 392 int expected_pushed_min{ 0 }, expected_pushed_max{ 0 };
393 // are we in batched mode? 393 // are we in batched mode?
394 kLindaBatched.pushKey(L); 394 kLindaBatched.pushKey(L_);
395 int const is_batched{ lua501_equal(L, key_i, -1) }; 395 int const is_batched{ lua501_equal(L_, key_i, -1) };
396 lua_pop(L, 1); 396 lua_pop(L_, 1);
397 if (is_batched) 397 if (is_batched)
398 { 398 {
399 // no need to pass linda.batched in the keeper state 399 // no need to pass linda.batched in the keeper state
400 ++key_i; 400 ++key_i;
401 // make sure the keys are of a valid type 401 // make sure the keys are of a valid type
402 check_key_types(L, key_i, key_i); 402 check_key_types(L_, key_i, key_i);
403 // receive multiple values from a single slot 403 // receive multiple values from a single slot
404 selected_keeper_receive = KEEPER_API(receive_batched); 404 selected_keeper_receive = KEEPER_API(receive_batched);
405 // we expect a user-defined amount of return value 405 // we expect a user-defined amount of return value
406 expected_pushed_min = (int) luaL_checkinteger(L, key_i + 1); 406 expected_pushed_min = (int) luaL_checkinteger(L_, key_i + 1);
407 expected_pushed_max = (int) luaL_optinteger(L, key_i + 2, expected_pushed_min); 407 expected_pushed_max = (int) luaL_optinteger(L_, key_i + 2, expected_pushed_min);
408 // don't forget to count the key in addition to the values 408 // don't forget to count the key in addition to the values
409 ++expected_pushed_min; 409 ++expected_pushed_min;
410 ++expected_pushed_max; 410 ++expected_pushed_max;
411 if (expected_pushed_min > expected_pushed_max) 411 if (expected_pushed_min > expected_pushed_max)
412 { 412 {
413 raise_luaL_error(L, "batched min/max error"); 413 raise_luaL_error(L_, "batched min/max error");
414 } 414 }
415 } 415 }
416 else 416 else
417 { 417 {
418 // make sure the keys are of a valid type 418 // make sure the keys are of a valid type
419 check_key_types(L, key_i, lua_gettop(L)); 419 check_key_types(L_, key_i, lua_gettop(L_));
420 // receive a single value, checking multiple slots 420 // receive a single value, checking multiple slots
421 selected_keeper_receive = KEEPER_API(receive); 421 selected_keeper_receive = KEEPER_API(receive);
422 // we expect a single (value, key) pair of returned values 422 // we expect a single (value, key) pair of returned values
423 expected_pushed_min = expected_pushed_max = 2; 423 expected_pushed_min = expected_pushed_max = 2;
424 } 424 }
425 425
426 Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L) }; 426 Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) };
427 Keeper* const K{ linda->whichKeeper() }; 427 Keeper* const K{ linda->whichKeeper() };
428 KeeperState const KL{ K ? K->L : nullptr }; 428 KeeperState const KL{ K ? K->L : nullptr };
429 if (KL == nullptr) 429 if (KL == nullptr)
@@ -447,16 +447,16 @@ LUAG_FUNC(linda_receive)
447 } 447 }
448 448
449 // all arguments of receive() but the first are passed to the keeper's receive function 449 // all arguments of receive() but the first are passed to the keeper's receive function
450 pushed = keeper_call(linda->U, KL, selected_keeper_receive, L, linda, key_i); 450 pushed = keeper_call(linda->U, KL, selected_keeper_receive, L_, linda, key_i);
451 if (!pushed.has_value()) 451 if (!pushed.has_value())
452 { 452 {
453 break; 453 break;
454 } 454 }
455 if (pushed.value() > 0) 455 if (pushed.value() > 0)
456 { 456 {
457 LUA_ASSERT(L, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max); 457 LUA_ASSERT(L_, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max);
458 // replace sentinels with real nils 458 // replace sentinels with real nils
459 keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed.value(), LookupMode::FromKeeper); 459 keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper);
460 // To be done from within the 'K' locking area 460 // To be done from within the 'K' locking area
461 // 461 //
462 linda->m_read_happened.notify_all(); 462 linda->m_read_happened.notify_all();
@@ -475,9 +475,9 @@ LUAG_FUNC(linda_receive)
475 { 475 {
476 // change status of lane to "waiting" 476 // change status of lane to "waiting"
477 prev_status = lane->m_status; // Running, most likely 477 prev_status = lane->m_status; // Running, most likely
478 LUA_ASSERT(L, prev_status == Lane::Running); // but check, just in case 478 LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case
479 lane->m_status = Lane::Waiting; 479 lane->m_status = Lane::Waiting;
480 LUA_ASSERT(L, lane->m_waiting_on == nullptr); 480 LUA_ASSERT(L_, lane->m_waiting_on == nullptr);
481 lane->m_waiting_on = &linda->m_write_happened; 481 lane->m_waiting_on = &linda->m_write_happened;
482 } 482 }
483 // not enough data to read: wakeup when data was sent, or when timeout is reached 483 // not enough data to read: wakeup when data was sent, or when timeout is reached
@@ -496,25 +496,25 @@ LUAG_FUNC(linda_receive)
496 496
497 if (!pushed.has_value()) 497 if (!pushed.has_value())
498 { 498 {
499 raise_luaL_error(L, "tried to copy unsupported types"); 499 raise_luaL_error(L_, "tried to copy unsupported types");
500 } 500 }
501 501
502 switch (cancel) 502 switch (cancel)
503 { 503 {
504 case CancelRequest::Soft: 504 case CancelRequest::Soft:
505 // if user wants to soft-cancel, the call returns kCancelError 505 // if user wants to soft-cancel, the call returns kCancelError
506 kCancelError.pushKey(L); 506 kCancelError.pushKey(L_);
507 return 1; 507 return 1;
508 508
509 case CancelRequest::Hard: 509 case CancelRequest::Hard:
510 // raise an error interrupting execution only in case of hard cancel 510 // raise an error interrupting execution only in case of hard cancel
511 raise_cancel_error(L); // raises an error and doesn't return 511 raise_cancel_error(L_); // raises an error and doesn't return
512 512
513 default: 513 default:
514 return pushed.value(); 514 return pushed.value();
515 } 515 }
516 }; 516 };
517 return Linda::ProtectedCall(L, receive); 517 return Linda::ProtectedCall(L_, receive);
518} 518}
519 519
520// ################################################################################################# 520// #################################################################################################
@@ -529,12 +529,12 @@ LUAG_FUNC(linda_receive)
529*/ 529*/
530LUAG_FUNC(linda_set) 530LUAG_FUNC(linda_set)
531{ 531{
532 auto set = [](lua_State* L) 532 auto set = [](lua_State* L_)
533 { 533 {
534 Linda* const linda{ ToLinda<false>(L, 1) }; 534 Linda* const linda{ ToLinda<false>(L_, 1) };
535 bool const has_value{ lua_gettop(L) > 2 }; 535 bool const has_value{ lua_gettop(L_) > 2 };
536 // make sure the key is of a valid type (throws an error if not the case) 536 // make sure the key is of a valid type (throws an error if not the case)
537 check_key_types(L, 2, 2); 537 check_key_types(L_, 2, 2);
538 538
539 Keeper* const K{ linda->whichKeeper() }; 539 Keeper* const K{ linda->whichKeeper() };
540 KeeperCallResult pushed; 540 KeeperCallResult pushed;
@@ -543,12 +543,12 @@ LUAG_FUNC(linda_set)
543 if (has_value) 543 if (has_value)
544 { 544 {
545 // convert nils to some special non-nil sentinel in sent values 545 // convert nils to some special non-nil sentinel in sent values
546 keeper_toggle_nil_sentinels(L, 3, LookupMode::ToKeeper); 546 keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper);
547 } 547 }
548 pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L, linda, 2); 548 pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L_, linda, 2);
549 if (pushed.has_value()) // no error? 549 if (pushed.has_value()) // no error?
550 { 550 {
551 LUA_ASSERT(L, pushed.value() == 0 || pushed.value() == 1); 551 LUA_ASSERT(L_, pushed.value() == 0 || pushed.value() == 1);
552 552
553 if (has_value) 553 if (has_value)
554 { 554 {
@@ -558,7 +558,7 @@ LUAG_FUNC(linda_set)
558 if (pushed.value() == 1) 558 if (pushed.value() == 1)
559 { 559 {
560 // the key was full, but it is no longer the case, tell writers they should wake 560 // the key was full, but it is no longer the case, tell writers they should wake
561 LUA_ASSERT(L, lua_type(L, -1) == LUA_TBOOLEAN && lua_toboolean(L, -1) == 1); 561 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1);
562 linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area 562 linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area
563 } 563 }
564 } 564 }
@@ -566,14 +566,14 @@ LUAG_FUNC(linda_set)
566 else // linda is cancelled 566 else // linda is cancelled
567 { 567 {
568 // do nothing and return lanes.cancel_error 568 // do nothing and return lanes.cancel_error
569 kCancelError.pushKey(L); 569 kCancelError.pushKey(L_);
570 pushed.emplace(1); 570 pushed.emplace(1);
571 } 571 }
572 572
573 // must trigger any error after keeper state has been released 573 // must trigger any error after keeper state has been released
574 return OptionalValue(pushed, L, "tried to copy unsupported types"); 574 return OptionalValue(pushed, L_, "tried to copy unsupported types");
575 }; 575 };
576 return Linda::ProtectedCall(L, set); 576 return Linda::ProtectedCall(L_, set);
577} 577}
578 578
579// ################################################################################################# 579// #################################################################################################
@@ -585,17 +585,17 @@ LUAG_FUNC(linda_set)
585 */ 585 */
586LUAG_FUNC(linda_count) 586LUAG_FUNC(linda_count)
587{ 587{
588 auto count = [](lua_State* L) 588 auto count = [](lua_State* L_)
589 { 589 {
590 Linda* const linda{ ToLinda<false>(L, 1) }; 590 Linda* const linda{ ToLinda<false>(L_, 1) };
591 // make sure the keys are of a valid type 591 // make sure the keys are of a valid type
592 check_key_types(L, 2, lua_gettop(L)); 592 check_key_types(L_, 2, lua_gettop(L_));
593 593
594 Keeper* const K{ linda->whichKeeper() }; 594 Keeper* const K{ linda->whichKeeper() };
595 KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L, linda, 2) }; 595 KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L_, linda, 2) };
596 return OptionalValue(pushed, L, "tried to count an invalid key"); 596 return OptionalValue(pushed, L_, "tried to count an invalid key");
597 }; 597 };
598 return Linda::ProtectedCall(L, count); 598 return Linda::ProtectedCall(L_, count);
599} 599}
600 600
601// ################################################################################################# 601// #################################################################################################
@@ -607,35 +607,35 @@ LUAG_FUNC(linda_count)
607*/ 607*/
608LUAG_FUNC(linda_get) 608LUAG_FUNC(linda_get)
609{ 609{
610 auto get = [](lua_State* L) 610 auto get = [](lua_State* L_)
611 { 611 {
612 Linda* const linda{ ToLinda<false>(L, 1) }; 612 Linda* const linda{ ToLinda<false>(L_, 1) };
613 lua_Integer const count{ luaL_optinteger(L, 3, 1) }; 613 lua_Integer const count{ luaL_optinteger(L_, 3, 1) };
614 luaL_argcheck(L, count >= 1, 3, "count should be >= 1"); 614 luaL_argcheck(L_, count >= 1, 3, "count should be >= 1");
615 luaL_argcheck(L, lua_gettop(L) <= 3, 4, "too many arguments"); 615 luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments");
616 // make sure the key is of a valid type (throws an error if not the case) 616 // make sure the key is of a valid type (throws an error if not the case)
617 check_key_types(L, 2, 2); 617 check_key_types(L_, 2, 2);
618 618
619 KeeperCallResult pushed; 619 KeeperCallResult pushed;
620 if (linda->simulate_cancel == CancelRequest::None) 620 if (linda->simulate_cancel == CancelRequest::None)
621 { 621 {
622 Keeper* const K{ linda->whichKeeper() }; 622 Keeper* const K{ linda->whichKeeper() };
623 pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L, linda, 2); 623 pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L_, linda, 2);
624 if (pushed.value_or(0) > 0) 624 if (pushed.value_or(0) > 0)
625 { 625 {
626 keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed.value(), LookupMode::FromKeeper); 626 keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper);
627 } 627 }
628 } 628 }
629 else // linda is cancelled 629 else // linda is cancelled
630 { 630 {
631 // do nothing and return lanes.cancel_error 631 // do nothing and return lanes.cancel_error
632 kCancelError.pushKey(L); 632 kCancelError.pushKey(L_);
633 pushed.emplace(1); 633 pushed.emplace(1);
634 } 634 }
635 // an error can be raised if we attempt to read an unregistered function 635 // an error can be raised if we attempt to read an unregistered function
636 return OptionalValue(pushed, L, "tried to copy unsupported types"); 636 return OptionalValue(pushed, L_, "tried to copy unsupported types");
637 }; 637 };
638 return Linda::ProtectedCall(L, get); 638 return Linda::ProtectedCall(L_, get);
639} 639}
640 640
641// ################################################################################################# 641// #################################################################################################
@@ -648,38 +648,38 @@ LUAG_FUNC(linda_get)
648*/ 648*/
649LUAG_FUNC(linda_limit) 649LUAG_FUNC(linda_limit)
650{ 650{
651 auto limit = [](lua_State* L) 651 auto limit = [](lua_State* L_)
652 { 652 {
653 Linda* const linda{ ToLinda<false>(L, 1) }; 653 Linda* const linda{ ToLinda<false>(L_, 1) };
654 // make sure we got 3 arguments: the linda, a key and a limit 654 // make sure we got 3 arguments: the linda, a key and a limit
655 luaL_argcheck( L, lua_gettop( L) == 3, 2, "wrong number of arguments"); 655 luaL_argcheck( L_, lua_gettop( L_) == 3, 2, "wrong number of arguments");
656 // make sure we got a numeric limit 656 // make sure we got a numeric limit
657 luaL_checknumber( L, 3); 657 luaL_checknumber( L_, 3);
658 // make sure the key is of a valid type 658 // make sure the key is of a valid type
659 check_key_types( L, 2, 2); 659 check_key_types( L_, 2, 2);
660 660
661 KeeperCallResult pushed; 661 KeeperCallResult pushed;
662 if (linda->simulate_cancel == CancelRequest::None) 662 if (linda->simulate_cancel == CancelRequest::None)
663 { 663 {
664 Keeper* const K{ linda->whichKeeper() }; 664 Keeper* const K{ linda->whichKeeper() };
665 pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L, linda, 2); 665 pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L_, linda, 2);
666 LUA_ASSERT(L, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads 666 LUA_ASSERT(L_, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads
667 if (pushed.value() == 1) 667 if (pushed.value() == 1)
668 { 668 {
669 LUA_ASSERT(L, lua_type( L, -1) == LUA_TBOOLEAN && lua_toboolean( L, -1) == 1); 669 LUA_ASSERT(L_, lua_type( L_, -1) == LUA_TBOOLEAN && lua_toboolean( L_, -1) == 1);
670 linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area 670 linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area
671 } 671 }
672 } 672 }
673 else // linda is cancelled 673 else // linda is cancelled
674 { 674 {
675 // do nothing and return lanes.cancel_error 675 // do nothing and return lanes.cancel_error
676 kCancelError.pushKey(L); 676 kCancelError.pushKey(L_);
677 pushed.emplace(1); 677 pushed.emplace(1);
678 } 678 }
679 // propagate pushed boolean if any 679 // propagate pushed boolean if any
680 return pushed.value(); 680 return pushed.value();
681 }; 681 };
682 return Linda::ProtectedCall(L, limit); 682 return Linda::ProtectedCall(L_, limit);
683} 683}
684 684
685// ################################################################################################# 685// #################################################################################################
@@ -691,10 +691,10 @@ LUAG_FUNC(linda_limit)
691*/ 691*/
692LUAG_FUNC(linda_cancel) 692LUAG_FUNC(linda_cancel)
693{ 693{
694 Linda* const linda{ ToLinda<false>(L, 1) }; 694 Linda* const linda{ ToLinda<false>(L_, 1) };
695 char const* who = luaL_optstring(L, 2, "both"); 695 char const* who = luaL_optstring(L_, 2, "both");
696 // make sure we got 3 arguments: the linda, a key and a limit 696 // make sure we got 3 arguments: the linda, a key and a limit
697 luaL_argcheck(L, lua_gettop(L) <= 2, 2, "wrong number of arguments"); 697 luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments");
698 698
699 linda->simulate_cancel = CancelRequest::Soft; 699 linda->simulate_cancel = CancelRequest::Soft;
700 if (strcmp(who, "both") == 0) // tell everyone writers to wake up 700 if (strcmp(who, "both") == 0) // tell everyone writers to wake up
@@ -716,7 +716,7 @@ LUAG_FUNC(linda_cancel)
716 } 716 }
717 else 717 else
718 { 718 {
719 raise_luaL_error(L, "unknown wake hint '%s'", who); 719 raise_luaL_error(L_, "unknown wake hint '%s'", who);
720 } 720 }
721 return 0; 721 return 0;
722} 722}
@@ -735,8 +735,8 @@ LUAG_FUNC(linda_cancel)
735*/ 735*/
736LUAG_FUNC(linda_deep) 736LUAG_FUNC(linda_deep)
737{ 737{
738 Linda* const linda{ ToLinda<false>(L, 1) }; 738 Linda* const linda{ ToLinda<false>(L_, 1) };
739 lua_pushlightuserdata(L, linda); // just the address 739 lua_pushlightuserdata(L_, linda); // just the address
740 return 1; 740 return 1;
741} 741}
742 742
@@ -751,9 +751,9 @@ LUAG_FUNC(linda_deep)
751*/ 751*/
752 752
753template <bool OPT> 753template <bool OPT>
754[[nodiscard]] static int LindaToString(lua_State* L, int idx_) 754[[nodiscard]] static int LindaToString(lua_State* L_, int idx_)
755{ 755{
756 Linda* const linda{ ToLinda<OPT>(L, idx_) }; 756 Linda* const linda{ ToLinda<OPT>(L_, idx_) };
757 if (linda != nullptr) 757 if (linda != nullptr)
758 { 758 {
759 char text[128]; 759 char text[128];
@@ -762,7 +762,7 @@ template <bool OPT>
762 len = sprintf(text, "Linda: %.*s", (int) sizeof(text) - 8, linda->getName()); 762 len = sprintf(text, "Linda: %.*s", (int) sizeof(text) - 8, linda->getName());
763 else 763 else
764 len = sprintf(text, "Linda: %p", linda); 764 len = sprintf(text, "Linda: %p", linda);
765 lua_pushlstring(L, text, len); 765 lua_pushlstring(L_, text, len);
766 return 1; 766 return 1;
767 } 767 }
768 return 0; 768 return 0;
@@ -770,7 +770,7 @@ template <bool OPT>
770 770
771LUAG_FUNC(linda_tostring) 771LUAG_FUNC(linda_tostring)
772{ 772{
773 return LindaToString<false>(L, 1); 773 return LindaToString<false>(L_, 1);
774} 774}
775 775
776// ################################################################################################# 776// #################################################################################################
@@ -786,21 +786,21 @@ LUAG_FUNC(linda_concat)
786{ // linda1? linda2? 786{ // linda1? linda2?
787 bool atLeastOneLinda{ false }; 787 bool atLeastOneLinda{ false };
788 // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. 788 // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both.
789 if (LindaToString<true>(L, 1)) 789 if (LindaToString<true>(L_, 1))
790 { 790 {
791 atLeastOneLinda = true; 791 atLeastOneLinda = true;
792 lua_replace(L, 1); 792 lua_replace(L_, 1);
793 } 793 }
794 if (LindaToString<true>(L, 2)) 794 if (LindaToString<true>(L_, 2))
795 { 795 {
796 atLeastOneLinda = true; 796 atLeastOneLinda = true;
797 lua_replace(L, 2); 797 lua_replace(L_, 2);
798 } 798 }
799 if (!atLeastOneLinda) // should not be possible 799 if (!atLeastOneLinda) // should not be possible
800 { 800 {
801 raise_luaL_error(L, "internal error: linda_concat called on non-Linda"); 801 raise_luaL_error(L_, "internal error: linda_concat called on non-Linda");
802 } 802 }
803 lua_concat(L, 2); 803 lua_concat(L_, 2);
804 return 1; 804 return 1;
805} 805}
806 806
@@ -812,12 +812,12 @@ LUAG_FUNC(linda_concat)
812 */ 812 */
813LUAG_FUNC(linda_dump) 813LUAG_FUNC(linda_dump)
814{ 814{
815 auto dump = [](lua_State* L) 815 auto dump = [](lua_State* L_)
816 { 816 {
817 Linda* const linda{ ToLinda<false>(L, 1) }; 817 Linda* const linda{ ToLinda<false>(L_, 1) };
818 return keeper_push_linda_storage(*linda, DestState{ L }); 818 return keeper_push_linda_storage(*linda, DestState{ L_ });
819 }; 819 };
820 return Linda::ProtectedCall(L, dump); 820 return Linda::ProtectedCall(L_, dump);
821} 821}
822 822
823// ################################################################################################# 823// #################################################################################################
@@ -828,12 +828,12 @@ LUAG_FUNC(linda_dump)
828 */ 828 */
829LUAG_FUNC(linda_towatch) 829LUAG_FUNC(linda_towatch)
830{ 830{
831 Linda* const linda{ ToLinda<false>(L, 1) }; 831 Linda* const linda{ ToLinda<false>(L_, 1) };
832 int pushed{ keeper_push_linda_storage(*linda, DestState{ L }) }; 832 int pushed{ keeper_push_linda_storage(*linda, DestState{ L_ }) };
833 if (pushed == 0) 833 if (pushed == 0)
834 { 834 {
835 // if the linda is empty, don't return nil 835 // if the linda is empty, don't return nil
836 pushed = LindaToString<false>(L, 1); 836 pushed = LindaToString<false>(L_, 1);
837 } 837 }
838 return pushed; 838 return pushed;
839} 839}
@@ -870,17 +870,17 @@ namespace global {
870 */ 870 */
871LUAG_FUNC(linda) 871LUAG_FUNC(linda)
872{ 872{
873 int const top{ lua_gettop(L) }; 873 int const top{ lua_gettop(L_) };
874 luaL_argcheck(L, top <= 2, top, "too many arguments"); 874 luaL_argcheck(L_, top <= 2, top, "too many arguments");
875 if (top == 1) 875 if (top == 1)
876 { 876 {
877 LuaType const t{ lua_type_as_enum(L, 1) }; 877 LuaType const t{ lua_type_as_enum(L_, 1) };
878 luaL_argcheck(L, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); 878 luaL_argcheck(L_, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)");
879 } 879 }
880 else if (top == 2) 880 else if (top == 2)
881 { 881 {
882 luaL_checktype(L, 1, LUA_TSTRING); 882 luaL_checktype(L_, 1, LUA_TSTRING);
883 luaL_checktype(L, 2, LUA_TNUMBER); 883 luaL_checktype(L_, 2, LUA_TNUMBER);
884 } 884 }
885 return LindaFactory::Instance.pushDeepUserdata(DestState{ L }, 0); 885 return LindaFactory::Instance.pushDeepUserdata(DestState{ L_ }, 0);
886} 886}
diff --git a/src/linda.h b/src/linda.h
index dbf48b3..7a21571 100644
--- a/src/linda.h
+++ b/src/linda.h
@@ -59,7 +59,7 @@ class Linda
59 Linda& operator=(Linda const&) = delete; 59 Linda& operator=(Linda const&) = delete;
60 Linda& operator=(Linda const&&) = delete; 60 Linda& operator=(Linda const&&) = delete;
61 61
62 [[nodiscard]] static int ProtectedCall(lua_State* L, lua_CFunction f_); 62 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_);
63 63
64 private: 64 private:
65 void setName(char const* name_, size_t len_); 65 void setName(char const* name_, size_t len_);
diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp
index 81e472d..3ee0ba4 100644
--- a/src/lindafactory.cpp
+++ b/src/lindafactory.cpp
@@ -49,7 +49,7 @@ void LindaFactory::createMetatable(lua_State* L_) const
49 lua_setfield(L_, -2, "__metatable"); 49 lua_setfield(L_, -2, "__metatable");
50 50
51 // the linda functions 51 // the linda functions
52 luaL_setfuncs(L_, mLindaMT, 0); 52 luaG_registerlibfuncs(L_, mLindaMT);
53 53
54 // some constants 54 // some constants
55 kLindaBatched.pushKey(L_); 55 kLindaBatched.pushKey(L_);
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h
index be331a1..dfde550 100644
--- a/src/macros_and_utils.h
+++ b/src/macros_and_utils.h
@@ -49,6 +49,7 @@ template <typename... ARGS>
49 49
50// ################################################################################################# 50// #################################################################################################
51 51
52#if LUA_VERSION_NUM >= 504
52// use this instead of Lua's luaL_typeerror 53// use this instead of Lua's luaL_typeerror
53template <typename... ARGS> 54template <typename... ARGS>
54[[noreturn]] static inline void raise_luaL_typeerror(lua_State* L_, int arg_, char const* tname_) 55[[noreturn]] static inline void raise_luaL_typeerror(lua_State* L_, int arg_, char const* tname_)
@@ -56,6 +57,7 @@ template <typename... ARGS>
56 std::ignore = luaL_typeerror(L_, arg_, tname_); // doesn't return 57 std::ignore = luaL_typeerror(L_, arg_, tname_); // doesn't return
57 assert(false); // we should never get here, but i'm paranoid 58 assert(false); // we should never get here, but i'm paranoid
58} 59}
60#endif // LUA_VERSION_NUM
59 61
60// ################################################################################################# 62// #################################################################################################
61 63
@@ -182,42 +184,42 @@ class StackChecker
182 184
183// ################################################################################################# 185// #################################################################################################
184 186
185inline void STACK_GROW(lua_State* L, int n_) 187inline void STACK_GROW(lua_State* L_, int n_)
186{ 188{
187 if (!lua_checkstack(L, n_)) { 189 if (!lua_checkstack(L_, n_)) {
188 raise_luaL_error(L, "Cannot grow stack!"); 190 raise_luaL_error(L_, "Cannot grow stack!");
189 } 191 }
190} 192}
191 193
192// ################################################################################################# 194// #################################################################################################
193 195
194#define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L) 196#define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L_)
195 197
196// ################################################################################################# 198// #################################################################################################
197 199
198// a small helper to extract a full userdata pointer from the stack in a safe way 200// a small helper to extract a full userdata pointer from the stack in a safe way
199template <typename T> 201template <typename T>
200[[nodiscard]] T* lua_tofulluserdata(lua_State* L, int index_) 202[[nodiscard]] T* lua_tofulluserdata(lua_State* L_, int index_)
201{ 203{
202 LUA_ASSERT(L, lua_isnil(L, index_) || lua_type(L, index_) == LUA_TUSERDATA); 204 LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_type(L_, index_) == LUA_TUSERDATA);
203 return static_cast<T*>(lua_touserdata(L, index_)); 205 return static_cast<T*>(lua_touserdata(L_, index_));
204} 206}
205 207
206template <typename T> 208template <typename T>
207[[nodiscard]] auto lua_tolightuserdata(lua_State* L, int index_) 209[[nodiscard]] auto lua_tolightuserdata(lua_State* L_, int index_)
208{ 210{
209 LUA_ASSERT(L, lua_isnil(L, index_) || lua_islightuserdata(L, index_)); 211 LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_islightuserdata(L_, index_));
210 if constexpr (std::is_pointer_v<T>) { 212 if constexpr (std::is_pointer_v<T>) {
211 return static_cast<T>(lua_touserdata(L, index_)); 213 return static_cast<T>(lua_touserdata(L_, index_));
212 } else { 214 } else {
213 return static_cast<T*>(lua_touserdata(L, index_)); 215 return static_cast<T*>(lua_touserdata(L_, index_));
214 } 216 }
215} 217}
216 218
217template <typename T> 219template <typename T>
218[[nodiscard]] T* lua_newuserdatauv(lua_State* L, int nuvalue_) 220[[nodiscard]] T* lua_newuserdatauv(lua_State* L_, int nuvalue_)
219{ 221{
220 return static_cast<T*>(lua_newuserdatauv(L, sizeof(T), nuvalue_)); 222 return static_cast<T*>(lua_newuserdatauv(L_, sizeof(T), nuvalue_));
221} 223}
222 224
223// ################################################################################################# 225// #################################################################################################
diff --git a/src/state.cpp b/src/state.cpp
index 9898812..d6dfb89 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -49,34 +49,34 @@ THE SOFTWARE.
49// 49//
50// Upvalues: [1]: original 'require' function 50// Upvalues: [1]: original 'require' function
51// 51//
52[[nodiscard]] static int luaG_new_require(lua_State* L) 52[[nodiscard]] static int luaG_new_require(lua_State* L_)
53{ 53{
54 int rc; 54 int rc;
55 int const args = lua_gettop( L); // args 55 int const args = lua_gettop( L_); // args
56 Universe* U = universe_get( L); 56 Universe* U = universe_get( L_);
57 //char const* modname = luaL_checkstring( L, 1); 57 //char const* modname = luaL_checkstring( L, 1);
58 58
59 STACK_GROW( L, 1); 59 STACK_GROW( L_, 1);
60 60
61 lua_pushvalue( L, lua_upvalueindex( 1)); // args require 61 lua_pushvalue( L_, lua_upvalueindex( 1)); // args require
62 lua_insert( L, 1); // require args 62 lua_insert( L_, 1); // require args
63 63
64 // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would 64 // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would
65 // leave us locked, blocking any future 'require' calls from other lanes. 65 // leave us locked, blocking any future 'require' calls from other lanes.
66 66
67 U->require_cs.lock(); 67 U->require_cs.lock();
68 // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET 68 // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET
69 rc = lua_pcall( L, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s) 69 rc = lua_pcall( L_, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s)
70 U->require_cs.unlock(); 70 U->require_cs.unlock();
71 71
72 // the required module (or an error message) is left on the stack as returned value by original require function 72 // the required module (or an error message) is left on the stack as returned value by original require function
73 73
74 if (rc != LUA_OK) // LUA_ERRRUN / LUA_ERRMEM ? 74 if (rc != LUA_OK) // LUA_ERRRUN / LUA_ERRMEM ?
75 { 75 {
76 raise_lua_error(L); 76 raise_lua_error(L_);
77 } 77 }
78 // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4 78 // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4
79 return lua_gettop(L); // result(s) 79 return lua_gettop(L_); // result(s)
80} 80}
81 81
82// ################################################################################################# 82// #################################################################################################
@@ -84,38 +84,38 @@ THE SOFTWARE.
84/* 84/*
85* Serialize calls to 'require', if it exists 85* Serialize calls to 'require', if it exists
86*/ 86*/
87void serialize_require(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) 87void serialize_require(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L_)
88{ 88{
89 STACK_GROW(L, 1); 89 STACK_GROW(L_, 1);
90 STACK_CHECK_START_REL(L, 0); 90 STACK_CHECK_START_REL(L_, 0);
91 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "serializing require()\n" INDENT_END)); 91 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "serializing require()\n" INDENT_END));
92 92
93 // Check 'require' is there and not already wrapped; if not, do nothing 93 // Check 'require' is there and not already wrapped; if not, do nothing
94 // 94 //
95 lua_getglobal(L, "require"); 95 lua_getglobal(L_, "require");
96 if (lua_isfunction(L, -1) && lua_tocfunction(L, -1) != luaG_new_require) 96 if (lua_isfunction(L_, -1) && lua_tocfunction(L_, -1) != luaG_new_require)
97 { 97 {
98 // [-1]: original 'require' function 98 // [-1]: original 'require' function
99 lua_pushcclosure(L, luaG_new_require, 1 /*upvalues*/); 99 lua_pushcclosure(L_, luaG_new_require, 1 /*upvalues*/);
100 lua_setglobal(L, "require"); 100 lua_setglobal(L_, "require");
101 } 101 }
102 else 102 else
103 { 103 {
104 // [-1]: nil 104 // [-1]: nil
105 lua_pop(L, 1); 105 lua_pop(L_, 1);
106 } 106 }
107 107
108 STACK_CHECK(L, 0); 108 STACK_CHECK(L_, 0);
109} 109}
110 110
111// ################################################################################################# 111// #################################################################################################
112 112
113/*---=== luaG_newstate ===---*/ 113/*---=== luaG_newstate ===---*/
114 114
115[[nodiscard]] static int require_lanes_core(lua_State* L) 115[[nodiscard]] static int require_lanes_core(lua_State* L_)
116{ 116{
117 // leaves a copy of 'lanes.core' module table on the stack 117 // leaves a copy of 'lanes.core' module table on the stack
118 luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); 118 luaL_requiref( L_, "lanes.core", luaopen_lanes_core, 0);
119 return 1; 119 return 1;
120} 120}
121 121
@@ -159,7 +159,7 @@ static luaL_Reg const libs[] =
159 159
160// ################################################################################################# 160// #################################################################################################
161 161
162static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, char const* name_, size_t len_) 162static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, char const* name_, size_t len_)
163{ 163{
164 for (int i{ 0 }; libs[i].name; ++i) 164 for (int i{ 0 }; libs[i].name; ++i)
165 { 165 {
@@ -171,16 +171,16 @@ static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, char const
171 { 171 {
172 bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" 172 bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core"
173 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); 173 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_));
174 STACK_CHECK_START_REL(L, 0); 174 STACK_CHECK_START_REL(L_, 0);
175 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) 175 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack)
176 luaL_requiref( L, name_, libfunc, !isLanesCore); 176 luaL_requiref( L_, name_, libfunc, !isLanesCore);
177 // lanes.core doesn't declare a global, so scan it here and now 177 // lanes.core doesn't declare a global, so scan it here and now
178 if (isLanesCore == true) 178 if (isLanesCore == true)
179 { 179 {
180 populate_func_lookup_table( L, -1, name_); 180 populate_func_lookup_table( L_, -1, name_);
181 } 181 }
182 lua_pop( L, 1); 182 lua_pop( L_, 1);
183 STACK_CHECK( L, 0); 183 STACK_CHECK( L_, 0);
184 } 184 }
185 break; 185 break;
186 } 186 }
@@ -208,33 +208,33 @@ static void copy_one_time_settings(Universe* U, SourceState L1, DestState L2)
208 raise_luaL_error(L1, "failed to copy settings when loading lanes.core"); 208 raise_luaL_error(L1, "failed to copy settings when loading lanes.core");
209 } 209 }
210 // set L2:_R[kConfigRegKey] = settings 210 // set L2:_R[kConfigRegKey] = settings
211 kConfigRegKey.setValue(L2, [](lua_State* L) { lua_insert(L, -2); }); // config 211 kConfigRegKey.setValue(L2, [](lua_State* L_) { lua_insert(L_, -2); }); // config
212 STACK_CHECK(L2, 0); 212 STACK_CHECK(L2, 0);
213 STACK_CHECK(L1, 0); 213 STACK_CHECK(L1, 0);
214} 214}
215 215
216// ################################################################################################# 216// #################################################################################################
217 217
218void initialize_on_state_create( Universe* U, lua_State* L) 218void initialize_on_state_create( Universe* U, lua_State* L_)
219{ 219{
220 STACK_CHECK_START_REL(L, 1); // settings 220 STACK_CHECK_START_REL(L_, 1); // settings
221 lua_getfield(L, -1, "on_state_create"); // settings on_state_create|nil 221 lua_getfield(L_, -1, "on_state_create"); // settings on_state_create|nil
222 if (!lua_isnil(L, -1)) 222 if (!lua_isnil(L_, -1))
223 { 223 {
224 // store C function pointer in an internal variable 224 // store C function pointer in an internal variable
225 U->on_state_create_func = lua_tocfunction(L, -1); // settings on_state_create 225 U->on_state_create_func = lua_tocfunction(L_, -1); // settings on_state_create
226 if (U->on_state_create_func != nullptr) 226 if (U->on_state_create_func != nullptr)
227 { 227 {
228 // make sure the function doesn't have upvalues 228 // make sure the function doesn't have upvalues
229 char const* upname = lua_getupvalue(L, -1, 1); // settings on_state_create upval? 229 char const* upname = lua_getupvalue(L_, -1, 1); // settings on_state_create upval?
230 if (upname != nullptr) // should be "" for C functions with upvalues if any 230 if (upname != nullptr) // should be "" for C functions with upvalues if any
231 { 231 {
232 raise_luaL_error(L, "on_state_create shouldn't have upvalues"); 232 raise_luaL_error(L_, "on_state_create shouldn't have upvalues");
233 } 233 }
234 // remove this C function from the config table so that it doesn't cause problems 234 // remove this C function from the config table so that it doesn't cause problems
235 // when we transfer the config table in newly created Lua states 235 // when we transfer the config table in newly created Lua states
236 lua_pushnil(L); // settings on_state_create nil 236 lua_pushnil(L_); // settings on_state_create nil
237 lua_setfield(L, -3, "on_state_create"); // settings on_state_create 237 lua_setfield(L_, -3, "on_state_create"); // settings on_state_create
238 } 238 }
239 else 239 else
240 { 240 {
@@ -242,8 +242,8 @@ void initialize_on_state_create( Universe* U, lua_State* L)
242 U->on_state_create_func = (lua_CFunction) initialize_on_state_create; 242 U->on_state_create_func = (lua_CFunction) initialize_on_state_create;
243 } 243 }
244 } 244 }
245 lua_pop(L, 1); // settings 245 lua_pop(L_, 1); // settings
246 STACK_CHECK(L, 1); 246 STACK_CHECK(L_, 1);
247} 247}
248 248
249// ################################################################################################# 249// #################################################################################################
@@ -281,16 +281,16 @@ lua_State* create_state(Universe* U, lua_State* from_)
281 281
282// ################################################################################################# 282// #################################################################################################
283 283
284void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMode mode_) 284void call_on_state_create(Universe* U, lua_State* L_, lua_State* from_, LookupMode mode_)
285{ 285{
286 if (U->on_state_create_func != nullptr) 286 if (U->on_state_create_func != nullptr)
287 { 287 {
288 STACK_CHECK_START_REL(L, 0); 288 STACK_CHECK_START_REL(L_, 0);
289 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); 289 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END));
290 if (U->on_state_create_func != (lua_CFunction) initialize_on_state_create) 290 if (U->on_state_create_func != (lua_CFunction) initialize_on_state_create)
291 { 291 {
292 // C function: recreate a closure in the new state, bypassing the lookup scheme 292 // C function: recreate a closure in the new state, bypassing the lookup scheme
293 lua_pushcfunction(L, U->on_state_create_func); // on_state_create() 293 lua_pushcfunction(L_, U->on_state_create_func); // on_state_create()
294 } 294 }
295 else // Lua function located in the config table, copied when we opened "lanes.core" 295 else // Lua function located in the config table, copied when we opened "lanes.core"
296 { 296 {
@@ -298,21 +298,21 @@ void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMod
298 { 298 {
299 // if attempting to call in a keeper state, do nothing because the function doesn't exist there 299 // if attempting to call in a keeper state, do nothing because the function doesn't exist there
300 // this doesn't count as an error though 300 // this doesn't count as an error though
301 STACK_CHECK(L, 0); 301 STACK_CHECK(L_, 0);
302 return; 302 return;
303 } 303 }
304 kConfigRegKey.pushValue(L); // {} 304 kConfigRegKey.pushValue(L_); // {}
305 STACK_CHECK(L, 1); 305 STACK_CHECK(L_, 1);
306 lua_getfield(L, -1, "on_state_create"); // {} on_state_create() 306 lua_getfield(L_, -1, "on_state_create"); // {} on_state_create()
307 lua_remove(L, -2); // on_state_create() 307 lua_remove(L_, -2); // on_state_create()
308 } 308 }
309 STACK_CHECK(L, 1); 309 STACK_CHECK(L_, 1);
310 // capture error and raise it in caller state 310 // capture error and raise it in caller state
311 if (lua_pcall(L, 0, 0, 0) != LUA_OK) 311 if (lua_pcall(L_, 0, 0, 0) != LUA_OK)
312 { 312 {
313 raise_luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L, -1) ? lua_tostring(L, -1) : lua_typename(L, lua_type(L, -1))); 313 raise_luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L_, -1) ? lua_tostring(L_, -1) : lua_typename(L_, lua_type(L_, -1)));
314 } 314 }
315 STACK_CHECK(L, 0); 315 STACK_CHECK(L_, 0);
316 } 316 }
317} 317}
318 318
@@ -344,7 +344,7 @@ lua_State* luaG_newstate(Universe* U, SourceState from_, char const* libs_)
344 STACK_CHECK(L, 0); 344 STACK_CHECK(L, 0);
345 345
346 // we'll need this every time we transfer some C function from/to this state 346 // we'll need this every time we transfer some C function from/to this state
347 kLookupRegKey.setValue(L, [](lua_State* L) { lua_newtable(L); }); 347 kLookupRegKey.setValue(L, [](lua_State* L_) { lua_newtable(L_); });
348 STACK_CHECK(L, 0); 348 STACK_CHECK(L, 0);
349 349
350 // neither libs (not even 'base') nor special init func: we are done 350 // neither libs (not even 'base') nor special init func: we are done
diff --git a/src/state.h b/src/state.h
index 2d65f16..9e43b41 100644
--- a/src/state.h
+++ b/src/state.h
@@ -6,7 +6,7 @@
6enum class LookupMode; 6enum class LookupMode;
7class Universe; 7class Universe;
8 8
9void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); 9void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_);
10 10
11// ################################################################################################# 11// #################################################################################################
12 12
@@ -15,5 +15,5 @@ void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L);
15 15
16// ################################################################################################# 16// #################################################################################################
17 17
18void initialize_on_state_create(Universe* U, lua_State* L); 18void initialize_on_state_create(Universe* U, lua_State* L_);
19void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMode mode_); 19void call_on_state_create(Universe* U, lua_State* L_, lua_State* from_, LookupMode mode_);
diff --git a/src/tools.cpp b/src/tools.cpp
index 2497ba7..e11cad5 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -45,34 +45,34 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull };
45/* 45/*
46 * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it 46 * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it
47 */ 47 */
48void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const char* mode_) 48void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_)
49{ 49{
50 STACK_GROW(L, 3); 50 STACK_GROW(L_, 3);
51 STACK_CHECK_START_REL(L, 0); 51 STACK_CHECK_START_REL(L_, 0);
52 52
53 key_.pushValue(L); // {}|nil 53 key_.pushValue(L_); // {}|nil
54 STACK_CHECK(L, 1); 54 STACK_CHECK(L_, 1);
55 55
56 if (lua_isnil(L, -1)) 56 if (lua_isnil(L_, -1))
57 { 57 {
58 lua_pop(L, 1); // 58 lua_pop(L_, 1); //
59 lua_newtable(L); // {} 59 lua_newtable(L_); // {}
60 // _R[key_] = {} 60 // _R[key_] = {}
61 key_.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // {} 61 key_.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // {}
62 STACK_CHECK(L, 1); 62 STACK_CHECK(L_, 1);
63 63
64 // Set its metatable if requested 64 // Set its metatable if requested
65 if (mode_) 65 if (mode_)
66 { 66 {
67 lua_newtable(L); // {} mt 67 lua_newtable(L_); // {} mt
68 lua_pushliteral(L, "__mode"); // {} mt "__mode" 68 lua_pushliteral(L_, "__mode"); // {} mt "__mode"
69 lua_pushstring(L, mode_); // {} mt "__mode" mode 69 lua_pushstring(L_, mode_); // {} mt "__mode" mode
70 lua_rawset(L, -3); // {} mt 70 lua_rawset(L_, -3); // {} mt
71 lua_setmetatable(L, -2); // {} 71 lua_setmetatable(L_, -2); // {}
72 } 72 }
73 } 73 }
74 STACK_CHECK(L, 1); 74 STACK_CHECK(L_, 1);
75 LUA_ASSERT(L, lua_istable(L, -1)); 75 LUA_ASSERT(L_, lua_istable(L_, -1));
76} 76}
77 77
78// ################################################################################################# 78// #################################################################################################
@@ -81,9 +81,9 @@ void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const cha
81 * Push a registry subtable (keyed by unique 'key_') onto the stack. 81 * Push a registry subtable (keyed by unique 'key_') onto the stack.
82 * If the subtable does not exist, it is created and chained. 82 * If the subtable does not exist, it is created and chained.
83 */ 83 */
84void push_registry_subtable(lua_State* L, RegistryUniqueKey key_) 84void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_)
85{ 85{
86 push_registry_subtable_mode(L, key_, nullptr); 86 push_registry_subtable_mode(L_, key_, nullptr);
87} 87}
88 88
89// ################################################################################################# 89// #################################################################################################
@@ -104,11 +104,11 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud,
104 104
105// ################################################################################################# 105// #################################################################################################
106 106
107[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L) 107[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_)
108{ 108{
109 Universe* const U{ universe_get(L) }; 109 Universe* const U{ universe_get(L_) };
110 // push a new full userdata on the stack, giving access to the universe's protected allocator 110 // push a new full userdata on the stack, giving access to the universe's protected allocator
111 [[maybe_unused]] AllocatorDefinition* const def{ new (L) AllocatorDefinition{ U->protected_allocator.makeDefinition() } }; 111 [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ U->protected_allocator.makeDefinition() } };
112 return 1; 112 return 1;
113} 113}
114 114
@@ -116,33 +116,33 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud,
116 116
117// called once at the creation of the universe (therefore L is the master Lua state everything originates from) 117// called once at the creation of the universe (therefore L is the master Lua state everything originates from)
118// Do I need to disable this when compiling for LuaJIT to prevent issues? 118// Do I need to disable this when compiling for LuaJIT to prevent issues?
119void initialize_allocator_function(Universe* U, lua_State* L) 119void initialize_allocator_function(Universe* U, lua_State* L_)
120{ 120{
121 STACK_CHECK_START_REL(L, 1); // settings 121 STACK_CHECK_START_REL(L_, 1); // settings
122 lua_getfield(L, -1, "allocator"); // settings allocator|nil|"protected" 122 lua_getfield(L_, -1, "allocator"); // settings allocator|nil|"protected"
123 if (!lua_isnil(L, -1)) 123 if (!lua_isnil(L_, -1))
124 { 124 {
125 // store C function pointer in an internal variable 125 // store C function pointer in an internal variable
126 U->provide_allocator = lua_tocfunction(L, -1); // settings allocator 126 U->provide_allocator = lua_tocfunction(L_, -1); // settings allocator
127 if (U->provide_allocator != nullptr) 127 if (U->provide_allocator != nullptr)
128 { 128 {
129 // make sure the function doesn't have upvalues 129 // make sure the function doesn't have upvalues
130 char const* upname = lua_getupvalue(L, -1, 1); // settings allocator upval? 130 char const* upname = lua_getupvalue(L_, -1, 1); // settings allocator upval?
131 if (upname != nullptr) // should be "" for C functions with upvalues if any 131 if (upname != nullptr) // should be "" for C functions with upvalues if any
132 { 132 {
133 raise_luaL_error(L, "config.allocator() shouldn't have upvalues"); 133 raise_luaL_error(L_, "config.allocator() shouldn't have upvalues");
134 } 134 }
135 // remove this C function from the config table so that it doesn't cause problems 135 // remove this C function from the config table so that it doesn't cause problems
136 // when we transfer the config table in newly created Lua states 136 // when we transfer the config table in newly created Lua states
137 lua_pushnil(L); // settings allocator nil 137 lua_pushnil(L_); // settings allocator nil
138 lua_setfield(L, -3, "allocator"); // settings allocator 138 lua_setfield(L_, -3, "allocator"); // settings allocator
139 } 139 }
140 else if (lua_type(L, -1) == LUA_TSTRING) // should be "protected" 140 else if (lua_type(L_, -1) == LUA_TSTRING) // should be "protected"
141 { 141 {
142 LUA_ASSERT(L, strcmp(lua_tostring(L, -1), "protected") == 0); 142 LUA_ASSERT(L_, strcmp(lua_tostring(L_, -1), "protected") == 0);
143 // set the original allocator to call from inside protection by the mutex 143 // set the original allocator to call from inside protection by the mutex
144 U->protected_allocator.initFrom(L); 144 U->protected_allocator.initFrom(L_);
145 U->protected_allocator.installIn(L); 145 U->protected_allocator.installIn(L_);
146 // before a state is created, this function will be called to obtain the allocator 146 // before a state is created, this function will be called to obtain the allocator
147 U->provide_allocator = luaG_provide_protected_allocator; 147 U->provide_allocator = luaG_provide_protected_allocator;
148 } 148 }
@@ -150,14 +150,14 @@ void initialize_allocator_function(Universe* U, lua_State* L)
150 else 150 else
151 { 151 {
152 // just grab whatever allocator was provided to lua_newstate 152 // just grab whatever allocator was provided to lua_newstate
153 U->protected_allocator.initFrom(L); 153 U->protected_allocator.initFrom(L_);
154 } 154 }
155 lua_pop(L, 1); // settings 155 lua_pop(L_, 1); // settings
156 STACK_CHECK(L, 1); 156 STACK_CHECK(L_, 1);
157 157
158 lua_getfield(L, -1, "internal_allocator"); // settings "libc"|"allocator" 158 lua_getfield(L_, -1, "internal_allocator"); // settings "libc"|"allocator"
159 { 159 {
160 char const* allocator = lua_tostring(L, -1); 160 char const* allocator = lua_tostring(L_, -1);
161 if (strcmp(allocator, "libc") == 0) 161 if (strcmp(allocator, "libc") == 0)
162 { 162 {
163 U->internal_allocator = AllocatorDefinition{ libc_lua_Alloc, nullptr }; 163 U->internal_allocator = AllocatorDefinition{ libc_lua_Alloc, nullptr };
@@ -173,15 +173,14 @@ void initialize_allocator_function(Universe* U, lua_State* L)
173 U->internal_allocator = U->protected_allocator; 173 U->internal_allocator = U->protected_allocator;
174 } 174 }
175 } 175 }
176 lua_pop(L, 1); // settings 176 lua_pop(L_, 1); // settings
177 STACK_CHECK(L, 1); 177 STACK_CHECK(L_, 1);
178} 178}
179 179
180// ################################################################################################# 180// #################################################################################################
181 181
182[[nodiscard]] static int dummy_writer(lua_State* L, void const* p, size_t sz, void* ud) 182[[nodiscard]] static int dummy_writer([[maybe_unused]] lua_State* L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_)
183{ 183{
184 (void)L; (void)p; (void)sz; (void) ud; // unused
185 return 666; 184 return 666;
186} 185}
187 186
@@ -207,24 +206,24 @@ enum class FuncSubType
207 FastJIT 206 FastJIT
208} ; 207} ;
209 208
210FuncSubType luaG_getfuncsubtype(lua_State* L, int _i) 209FuncSubType luaG_getfuncsubtype(lua_State* L_, int _i)
211{ 210{
212 if (lua_tocfunction(L, _i)) // nullptr for LuaJIT-fast && bytecode functions 211 if (lua_tocfunction(L_, _i)) // nullptr for LuaJIT-fast && bytecode functions
213 { 212 {
214 return FuncSubType::Native; 213 return FuncSubType::Native;
215 } 214 }
216 { 215 {
217 int mustpush{ 0 }; 216 int mustpush{ 0 };
218 if (lua_absindex(L, _i) != lua_gettop(L)) 217 if (lua_absindex(L_, _i) != lua_gettop(L_))
219 { 218 {
220 lua_pushvalue(L, _i); 219 lua_pushvalue(L_, _i);
221 mustpush = 1; 220 mustpush = 1;
222 } 221 }
223 // the provided writer fails with code 666 222 // the provided writer fails with code 666
224 // therefore, anytime we get 666, this means that lua_dump() attempted a dump 223 // therefore, anytime we get 666, this means that lua_dump() attempted a dump
225 // all other cases mean this is either a C or LuaJIT-fast function 224 // all other cases mean this is either a C or LuaJIT-fast function
226 int const dumpres{ lua504_dump(L, dummy_writer, nullptr, 0) }; 225 int const dumpres{ lua504_dump(L_, dummy_writer, nullptr, 0) };
227 lua_pop(L, mustpush); 226 lua_pop(L_, mustpush);
228 if (dumpres == 666) 227 if (dumpres == 666)
229 { 228 {
230 return FuncSubType::Bytecode; 229 return FuncSubType::Bytecode;
@@ -236,28 +235,28 @@ FuncSubType luaG_getfuncsubtype(lua_State* L, int _i)
236// ################################################################################################# 235// #################################################################################################
237 236
238// inspired from tconcat() in ltablib.c 237// inspired from tconcat() in ltablib.c
239[[nodiscard]] static char const* luaG_pushFQN(lua_State* L, int t, int last, size_t* length) 238[[nodiscard]] static char const* luaG_pushFQN(lua_State* L_, int t, int last, size_t* length)
240{ 239{
241 luaL_Buffer b; 240 luaL_Buffer b;
242 STACK_CHECK_START_REL(L, 0); 241 STACK_CHECK_START_REL(L_, 0);
243 // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... 242 // Lua 5.4 pushes &b as light userdata on the stack. be aware of it...
244 luaL_buffinit(L, &b); // ... {} ... &b? 243 luaL_buffinit(L_, &b); // ... {} ... &b?
245 int i = 1; 244 int i = 1;
246 for (; i < last; ++i) 245 for (; i < last; ++i)
247 { 246 {
248 lua_rawgeti( L, t, i); 247 lua_rawgeti( L_, t, i);
249 luaL_addvalue( &b); 248 luaL_addvalue( &b);
250 luaL_addlstring(&b, "/", 1); 249 luaL_addlstring(&b, "/", 1);
251 } 250 }
252 if (i == last) // add last value (if interval was not empty) 251 if (i == last) // add last value (if interval was not empty)
253 { 252 {
254 lua_rawgeti(L, t, i); 253 lua_rawgeti(L_, t, i);
255 luaL_addvalue(&b); 254 luaL_addvalue(&b);
256 } 255 }
257 // &b is popped at that point (-> replaced by the result) 256 // &b is popped at that point (-> replaced by the result)
258 luaL_pushresult(&b); // ... {} ... "<result>" 257 luaL_pushresult(&b); // ... {} ... "<result>"
259 STACK_CHECK(L, 1); 258 STACK_CHECK(L_, 1);
260 return lua_tolstring( L, -1, length); 259 return lua_tolstring( L_, -1, length);
261} 260}
262 261
263// ################################################################################################# 262// #################################################################################################
@@ -270,7 +269,7 @@ FuncSubType luaG_getfuncsubtype(lua_State* L, int _i)
270 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter 269 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter
271 * pops the processed object from the stack 270 * pops the processed object from the stack
272 */ 271 */
273static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _depth) 272static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, int _ctx_base, int _depth)
274{ 273{
275 // slot 1 in the stack contains the table that receives everything we found 274 // slot 1 in the stack contains the table that receives everything we found
276 int const dest{ _ctx_base }; 275 int const dest{ _ctx_base };
@@ -283,18 +282,18 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L,
283 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); 282 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END));
284 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 283 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
285 284
286 STACK_CHECK_START_REL(L, 0); 285 STACK_CHECK_START_REL(L_, 0);
287 // first, raise an error if the function is already known 286 // first, raise an error if the function is already known
288 lua_pushvalue(L, -1); // ... {bfc} k o o 287 lua_pushvalue(L_, -1); // ... {bfc} k o o
289 lua_rawget(L, dest); // ... {bfc} k o name? 288 lua_rawget(L_, dest); // ... {bfc} k o name?
290 prevName = lua_tolstring( L, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object) 289 prevName = lua_tolstring( L_, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object)
291 // push name in fqn stack (note that concatenation will crash if name is a not string or a number) 290 // push name in fqn stack (note that concatenation will crash if name is a not string or a number)
292 lua_pushvalue(L, -3); // ... {bfc} k o name? k 291 lua_pushvalue(L_, -3); // ... {bfc} k o name? k
293 LUA_ASSERT(L, lua_type(L, -1) == LUA_TNUMBER || lua_type(L, -1) == LUA_TSTRING); 292 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING);
294 ++_depth; 293 ++_depth;
295 lua_rawseti(L, fqn, _depth); // ... {bfc} k o name? 294 lua_rawseti(L_, fqn, _depth); // ... {bfc} k o name?
296 // generate name 295 // generate name
297 DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n" 296 DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L_, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n"
298 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order 297 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order
299 // on different VMs even when the tables are populated the exact same way. 298 // on different VMs even when the tables are populated the exact same way.
300 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), 299 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL),
@@ -304,11 +303,11 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L,
304 // Also, nothing prevents any external module from exposing a given object under several names, so... 303 // Also, nothing prevents any external module from exposing a given object under several names, so...
305 // Therefore, when we encounter an object for which a name was previously registered, we need to select the names 304 // Therefore, when we encounter an object for which a name was previously registered, we need to select the names
306 // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded 305 // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded
307 if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L, -2, -1))) 306 if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L_, -2, -1)))
308 { 307 {
309 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName)); 308 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName));
310 // the previous name is 'smaller' than the one we just generated: keep it! 309 // the previous name is 'smaller' than the one we just generated: keep it!
311 lua_pop(L, 3); // ... {bfc} k 310 lua_pop(L_, 3); // ... {bfc} k
312 } 311 }
313 else 312 else
314 { 313 {
@@ -316,63 +315,63 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L,
316 if (prevName) 315 if (prevName)
317 { 316 {
318 // clear the previous name for the database to avoid clutter 317 // clear the previous name for the database to avoid clutter
319 lua_insert(L, -2); // ... {bfc} k o "f.q.n" prevName 318 lua_insert(L_, -2); // ... {bfc} k o "f.q.n" prevName
320 // t[prevName] = nil 319 // t[prevName] = nil
321 lua_pushnil(L); // ... {bfc} k o "f.q.n" prevName nil 320 lua_pushnil(L_); // ... {bfc} k o "f.q.n" prevName nil
322 lua_rawset(L, dest); // ... {bfc} k o "f.q.n" 321 lua_rawset(L_, dest); // ... {bfc} k o "f.q.n"
323 } 322 }
324 else 323 else
325 { 324 {
326 lua_remove(L, -2); // ... {bfc} k o "f.q.n" 325 lua_remove(L_, -2); // ... {bfc} k o "f.q.n"
327 } 326 }
328 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename(L, lua_type( L, -2)), newName)); 327 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename(L, lua_type( L, -2)), newName));
329 // prepare the stack for database feed 328 // prepare the stack for database feed
330 lua_pushvalue(L, -1); // ... {bfc} k o "f.q.n" "f.q.n" 329 lua_pushvalue(L_, -1); // ... {bfc} k o "f.q.n" "f.q.n"
331 lua_pushvalue(L, -3); // ... {bfc} k o "f.q.n" "f.q.n" o 330 lua_pushvalue(L_, -3); // ... {bfc} k o "f.q.n" "f.q.n" o
332 LUA_ASSERT(L, lua_rawequal(L, -1, -4)); 331 LUA_ASSERT(L_, lua_rawequal(L_, -1, -4));
333 LUA_ASSERT(L, lua_rawequal(L, -2, -3)); 332 LUA_ASSERT(L_, lua_rawequal(L_, -2, -3));
334 // t["f.q.n"] = o 333 // t["f.q.n"] = o
335 lua_rawset(L, dest); // ... {bfc} k o "f.q.n" 334 lua_rawset(L_, dest); // ... {bfc} k o "f.q.n"
336 // t[o] = "f.q.n" 335 // t[o] = "f.q.n"
337 lua_rawset(L, dest); // ... {bfc} k 336 lua_rawset(L_, dest); // ... {bfc} k
338 // remove table name from fqn stack 337 // remove table name from fqn stack
339 lua_pushnil(L); // ... {bfc} k nil 338 lua_pushnil(L_); // ... {bfc} k nil
340 lua_rawseti(L, fqn, _depth); // ... {bfc} k 339 lua_rawseti(L_, fqn, _depth); // ... {bfc} k
341 } 340 }
342 -- _depth; 341 -- _depth;
343 STACK_CHECK(L, -1); 342 STACK_CHECK(L_, -1);
344} 343}
345 344
346// ################################################################################################# 345// #################################################################################################
347 346
348static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) 347static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L_, int _ctx_base, int _i, int _depth)
349{ 348{
350 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i 349 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i
351 int const fqn = _ctx_base + 1; 350 int const fqn = _ctx_base + 1;
352 // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops 351 // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops
353 int const cache = _ctx_base + 2; 352 int const cache = _ctx_base + 2;
354 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) 353 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search)
355 int const breadth_first_cache = lua_gettop(L) + 1; 354 int const breadth_first_cache = lua_gettop(L_) + 1;
356 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END)); 355 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END));
357 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 356 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
358 357
359 STACK_GROW(L, 6); 358 STACK_GROW(L_, 6);
360 // slot _i contains a table where we search for functions (or a full userdata with a metatable) 359 // slot _i contains a table where we search for functions (or a full userdata with a metatable)
361 STACK_CHECK_START_REL(L, 0); // ... {_i} 360 STACK_CHECK_START_REL(L_, 0); // ... {_i}
362 361
363 // if object is a userdata, replace it by its metatable 362 // if object is a userdata, replace it by its metatable
364 if (lua_type(L, _i) == LUA_TUSERDATA) 363 if (lua_type(L_, _i) == LUA_TUSERDATA)
365 { 364 {
366 lua_getmetatable(L, _i); // ... {_i} mt 365 lua_getmetatable(L_, _i); // ... {_i} mt
367 lua_replace(L, _i); // ... {_i} 366 lua_replace(L_, _i); // ... {_i}
368 } 367 }
369 368
370 // if table is already visited, we are done 369 // if table is already visited, we are done
371 lua_pushvalue(L, _i); // ... {_i} {} 370 lua_pushvalue(L_, _i); // ... {_i} {}
372 lua_rawget(L, cache); // ... {_i} nil|n 371 lua_rawget(L_, cache); // ... {_i} nil|n
373 lua_Integer visit_count{ lua_tointeger(L, -1) }; // 0 if nil, else n 372 lua_Integer visit_count{ lua_tointeger(L_, -1) }; // 0 if nil, else n
374 lua_pop(L, 1); // ... {_i} 373 lua_pop(L_, 1); // ... {_i}
375 STACK_CHECK(L, 0); 374 STACK_CHECK(L_, 0);
376 if (visit_count > 0) 375 if (visit_count > 0)
377 { 376 {
378 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); 377 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END));
@@ -380,88 +379,88 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U)
380 } 379 }
381 380
382 // remember we visited this table (1-visit count) 381 // remember we visited this table (1-visit count)
383 lua_pushvalue(L, _i); // ... {_i} {} 382 lua_pushvalue(L_, _i); // ... {_i} {}
384 lua_pushinteger(L, visit_count + 1); // ... {_i} {} 1 383 lua_pushinteger(L_, visit_count + 1); // ... {_i} {} 1
385 lua_rawset(L, cache); // ... {_i} 384 lua_rawset(L_, cache); // ... {_i}
386 STACK_CHECK(L, 0); 385 STACK_CHECK(L_, 0);
387 386
388 // this table is at breadth_first_cache index 387 // this table is at breadth_first_cache index
389 lua_newtable(L); // ... {_i} {bfc} 388 lua_newtable(L_); // ... {_i} {bfc}
390 LUA_ASSERT(L, lua_gettop(L) == breadth_first_cache); 389 LUA_ASSERT(L_, lua_gettop(L_) == breadth_first_cache);
391 // iterate over all entries in the processed table 390 // iterate over all entries in the processed table
392 lua_pushnil(L); // ... {_i} {bfc} nil 391 lua_pushnil(L_); // ... {_i} {bfc} nil
393 while( lua_next(L, _i) != 0) // ... {_i} {bfc} k v 392 while( lua_next(L_, _i) != 0) // ... {_i} {bfc} k v
394 { 393 {
395 // just for debug, not actually needed 394 // just for debug, not actually needed
396 //char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"; 395 //char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string";
397 // subtable: process it recursively 396 // subtable: process it recursively
398 if (lua_istable(L, -1)) // ... {_i} {bfc} k {} 397 if (lua_istable(L_, -1)) // ... {_i} {bfc} k {}
399 { 398 {
400 // increment visit count to make sure we will actually scan it at this recursive level 399 // increment visit count to make sure we will actually scan it at this recursive level
401 lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} 400 lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {}
402 lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} {} 401 lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {} {}
403 lua_rawget(L, cache); // ... {_i} {bfc} k {} {} n? 402 lua_rawget(L_, cache); // ... {_i} {bfc} k {} {} n?
404 visit_count = lua_tointeger(L, -1) + 1; // 1 if we got nil, else n+1 403 visit_count = lua_tointeger(L_, -1) + 1; // 1 if we got nil, else n+1
405 lua_pop(L, 1); // ... {_i} {bfc} k {} {} 404 lua_pop(L_, 1); // ... {_i} {bfc} k {} {}
406 lua_pushinteger(L, visit_count); // ... {_i} {bfc} k {} {} n 405 lua_pushinteger(L_, visit_count); // ... {_i} {bfc} k {} {} n
407 lua_rawset(L, cache); // ... {_i} {bfc} k {} 406 lua_rawset(L_, cache); // ... {_i} {bfc} k {}
408 // store the table in the breadth-first cache 407 // store the table in the breadth-first cache
409 lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k 408 lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k
410 lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k {} 409 lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k {}
411 lua_rawset(L, breadth_first_cache); // ... {_i} {bfc} k {} 410 lua_rawset(L_, breadth_first_cache); // ... {_i} {bfc} k {}
412 // generate a name, and if we already had one name, keep whichever is the shorter 411 // generate a name, and if we already had one name, keep whichever is the shorter
413 update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, _depth); // ... {_i} {bfc} k 412 update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, _depth); // ... {_i} {bfc} k
414 } 413 }
415 else if (lua_isfunction(L, -1) && (luaG_getfuncsubtype(L, -1) != FuncSubType::Bytecode)) 414 else if (lua_isfunction(L_, -1) && (luaG_getfuncsubtype(L_, -1) != FuncSubType::Bytecode))
416 { 415 {
417 // generate a name, and if we already had one name, keep whichever is the shorter 416 // generate a name, and if we already had one name, keep whichever is the shorter
418 // this pops the function from the stack 417 // this pops the function from the stack
419 update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, _depth); // ... {_i} {bfc} k 418 update_lookup_entry( DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, _depth); // ... {_i} {bfc} k
420 } 419 }
421 else 420 else
422 { 421 {
423 lua_pop(L, 1); // ... {_i} {bfc} k 422 lua_pop(L_, 1); // ... {_i} {bfc} k
424 } 423 }
425 STACK_CHECK(L, 2); 424 STACK_CHECK(L_, 2);
426 } 425 }
427 // now process the tables we encountered at that depth 426 // now process the tables we encountered at that depth
428 ++ _depth; 427 ++ _depth;
429 lua_pushnil(L); // ... {_i} {bfc} nil 428 lua_pushnil(L_); // ... {_i} {bfc} nil
430 while (lua_next(L, breadth_first_cache) != 0) // ... {_i} {bfc} k {} 429 while (lua_next(L_, breadth_first_cache) != 0) // ... {_i} {bfc} k {}
431 { 430 {
432 DEBUGSPEW_CODE(char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string"); 431 DEBUGSPEW_CODE(char const* key = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : "not a string");
433 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); 432 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key));
434 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 433 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
435 // un-visit this table in case we do need to process it 434 // un-visit this table in case we do need to process it
436 lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} 435 lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {}
437 lua_rawget(L, cache); // ... {_i} {bfc} k {} n 436 lua_rawget(L_, cache); // ... {_i} {bfc} k {} n
438 LUA_ASSERT(L, lua_type(L, -1) == LUA_TNUMBER); 437 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER);
439 visit_count = lua_tointeger(L, -1) - 1; 438 visit_count = lua_tointeger(L_, -1) - 1;
440 lua_pop(L, 1); // ... {_i} {bfc} k {} 439 lua_pop(L_, 1); // ... {_i} {bfc} k {}
441 lua_pushvalue(L, -1); // ... {_i} {bfc} k {} {} 440 lua_pushvalue(L_, -1); // ... {_i} {bfc} k {} {}
442 if (visit_count > 0) 441 if (visit_count > 0)
443 { 442 {
444 lua_pushinteger(L, visit_count); // ... {_i} {bfc} k {} {} n 443 lua_pushinteger(L_, visit_count); // ... {_i} {bfc} k {} {} n
445 } 444 }
446 else 445 else
447 { 446 {
448 lua_pushnil(L); // ... {_i} {bfc} k {} {} nil 447 lua_pushnil(L_); // ... {_i} {bfc} k {} {} nil
449 } 448 }
450 lua_rawset(L, cache); // ... {_i} {bfc} k {} 449 lua_rawset(L_, cache); // ... {_i} {bfc} k {}
451 // push table name in fqn stack (note that concatenation will crash if name is a not string!) 450 // push table name in fqn stack (note that concatenation will crash if name is a not string!)
452 lua_pushvalue(L, -2); // ... {_i} {bfc} k {} k 451 lua_pushvalue(L_, -2); // ... {_i} {bfc} k {} k
453 lua_rawseti(L, fqn, _depth); // ... {_i} {bfc} k {} 452 lua_rawseti(L_, fqn, _depth); // ... {_i} {bfc} k {}
454 populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L, _ctx_base, lua_gettop(L), _depth); 453 populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, _ctx_base, lua_gettop(L_), _depth);
455 lua_pop(L, 1); // ... {_i} {bfc} k 454 lua_pop(L_, 1); // ... {_i} {bfc} k
456 STACK_CHECK(L, 2); 455 STACK_CHECK(L_, 2);
457 } 456 }
458 // remove table name from fqn stack 457 // remove table name from fqn stack
459 lua_pushnil(L); // ... {_i} {bfc} nil 458 lua_pushnil(L_); // ... {_i} {bfc} nil
460 lua_rawseti(L, fqn, _depth); // ... {_i} {bfc} 459 lua_rawseti(L_, fqn, _depth); // ... {_i} {bfc}
461 -- _depth; 460 -- _depth;
462 // we are done with our cache 461 // we are done with our cache
463 lua_pop(L, 1); // ... {_i} 462 lua_pop(L_, 1); // ... {_i}
464 STACK_CHECK(L, 0); 463 STACK_CHECK(L_, 0);
465 // we are done // ... {_i} {bfc} 464 // we are done // ... {_i} {bfc}
466} 465}
467 466
@@ -470,64 +469,64 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U)
470/* 469/*
471 * create a "fully.qualified.name" <-> function equivalence database 470 * create a "fully.qualified.name" <-> function equivalence database
472 */ 471 */
473void populate_func_lookup_table(lua_State* L, int i_, char const* name_) 472void populate_func_lookup_table(lua_State* L_, int i_, char const* name_)
474{ 473{
475 int const ctx_base = lua_gettop(L) + 1; 474 int const ctx_base = lua_gettop(L_) + 1;
476 int const in_base = lua_absindex(L, i_); 475 int const in_base = lua_absindex(L_, i_);
477 int start_depth = 0; 476 int start_depth = 0;
478 DEBUGSPEW_CODE(Universe* U = universe_get(L)); 477 DEBUGSPEW_CODE(Universe* U = universe_get(L));
479 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); 478 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr"));
480 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); 479 DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U });
481 STACK_GROW(L, 3); 480 STACK_GROW(L_, 3);
482 STACK_CHECK_START_REL(L, 0); 481 STACK_CHECK_START_REL(L_, 0);
483 kLookupRegKey.pushValue(L); // {} 482 kLookupRegKey.pushValue(L_); // {}
484 STACK_CHECK(L, 1); 483 STACK_CHECK(L_, 1);
485 LUA_ASSERT(L, lua_istable(L, -1)); 484 LUA_ASSERT(L_, lua_istable(L_, -1));
486 if (lua_type(L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function 485 if (lua_type(L_, in_base) == LUA_TFUNCTION) // for example when a module is a simple function
487 { 486 {
488 name_ = name_ ? name_ : "nullptr"; 487 name_ = name_ ? name_ : "nullptr";
489 lua_pushvalue(L, in_base); // {} f 488 lua_pushvalue(L_, in_base); // {} f
490 lua_pushstring(L, name_); // {} f _name 489 lua_pushstring(L_, name_); // {} f _name
491 lua_rawset(L, -3); // {} 490 lua_rawset(L_, -3); // {}
492 lua_pushstring(L, name_); // {} _name 491 lua_pushstring(L_, name_); // {} _name
493 lua_pushvalue(L, in_base); // {} _name f 492 lua_pushvalue(L_, in_base); // {} _name f
494 lua_rawset(L, -3); // {} 493 lua_rawset(L_, -3); // {}
495 lua_pop(L, 1); // 494 lua_pop(L_, 1); //
496 } 495 }
497 else if (lua_type(L, in_base) == LUA_TTABLE) 496 else if (lua_type(L_, in_base) == LUA_TTABLE)
498 { 497 {
499 lua_newtable(L); // {} {fqn} 498 lua_newtable(L_); // {} {fqn}
500 if (name_) 499 if (name_)
501 { 500 {
502 STACK_CHECK(L, 2); 501 STACK_CHECK(L_, 2);
503 lua_pushstring(L, name_); // {} {fqn} "name" 502 lua_pushstring(L_, name_); // {} {fqn} "name"
504 // generate a name, and if we already had one name, keep whichever is the shorter 503 // generate a name, and if we already had one name, keep whichever is the shorter
505 lua_pushvalue(L, in_base); // {} {fqn} "name" t 504 lua_pushvalue(L_, in_base); // {} {fqn} "name" t
506 update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L, ctx_base, start_depth); // {} {fqn} "name" 505 update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L_, ctx_base, start_depth); // {} {fqn} "name"
507 // don't forget to store the name at the bottom of the fqn stack 506 // don't forget to store the name at the bottom of the fqn stack
508 ++ start_depth; 507 ++ start_depth;
509 lua_rawseti(L, -2, start_depth); // {} {fqn} 508 lua_rawseti(L_, -2, start_depth); // {} {fqn}
510 STACK_CHECK(L, 2); 509 STACK_CHECK(L_, 2);
511 } 510 }
512 // retrieve the cache, create it if we haven't done it yet 511 // retrieve the cache, create it if we haven't done it yet
513 kLookupCacheRegKey.pushValue(L); // {} {fqn} {cache}? 512 kLookupCacheRegKey.pushValue(L_); // {} {fqn} {cache}?
514 if (lua_isnil(L, -1)) 513 if (lua_isnil(L_, -1))
515 { 514 {
516 lua_pop(L, 1); // {} {fqn} 515 lua_pop(L_, 1); // {} {fqn}
517 lua_newtable(L); // {} {fqn} {cache} 516 lua_newtable(L_); // {} {fqn} {cache}
518 kLookupCacheRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 517 kLookupCacheRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); });
519 STACK_CHECK(L, 3); 518 STACK_CHECK(L_, 3);
520 } 519 }
521 // process everything we find in that table, filling in lookup data for all functions and tables we see there 520 // process everything we find in that table, filling in lookup data for all functions and tables we see there
522 populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L, ctx_base, in_base, start_depth); 521 populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, ctx_base, in_base, start_depth);
523 lua_pop(L, 3); 522 lua_pop(L_, 3);
524 } 523 }
525 else 524 else
526 { 525 {
527 lua_pop(L, 1); // 526 lua_pop(L_, 1); //
528 raise_luaL_error(L, "unsupported module type %s", lua_typename(L, lua_type(L, in_base))); 527 raise_luaL_error(L_, "unsupported module type %s", lua_typename(L_, lua_type(L_, in_base)));
529 } 528 }
530 STACK_CHECK(L, 0); 529 STACK_CHECK(L_, 0);
531} 530}
532 531
533// ################################################################################################# 532// #################################################################################################
@@ -540,36 +539,36 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
540/* 539/*
541* Get a unique ID for metatable at [i]. 540* Get a unique ID for metatable at [i].
542*/ 541*/
543[[nodiscard]] static lua_Integer get_mt_id(Universe* U, lua_State* L, int i) 542[[nodiscard]] static lua_Integer get_mt_id(Universe* U, lua_State* L_, int i)
544{ 543{
545 i = lua_absindex(L, i); 544 i = lua_absindex(L_, i);
546 545
547 STACK_GROW(L, 3); 546 STACK_GROW(L_, 3);
548 547
549 STACK_CHECK_START_REL(L, 0); 548 STACK_CHECK_START_REL(L_, 0);
550 push_registry_subtable(L, kMtIdRegKey); // ... _R[kMtIdRegKey] 549 push_registry_subtable(L_, kMtIdRegKey); // ... _R[kMtIdRegKey]
551 lua_pushvalue(L, i); // ... _R[kMtIdRegKey] {mt} 550 lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] {mt}
552 lua_rawget(L, -2); // ... _R[kMtIdRegKey] mtk? 551 lua_rawget(L_, -2); // ... _R[kMtIdRegKey] mtk?
553 552
554 lua_Integer id{ lua_tointeger(L, -1) }; // 0 for nil 553 lua_Integer id{ lua_tointeger(L_, -1) }; // 0 for nil
555 lua_pop(L, 1); // ... _R[kMtIdRegKey] 554 lua_pop(L_, 1); // ... _R[kMtIdRegKey]
556 STACK_CHECK(L, 1); 555 STACK_CHECK(L_, 1);
557 556
558 if (id == 0) 557 if (id == 0)
559 { 558 {
560 id = U->next_mt_id.fetch_add(1, std::memory_order_relaxed); 559 id = U->next_mt_id.fetch_add(1, std::memory_order_relaxed);
561 560
562 // Create two-way references: id_uint <-> table 561 // Create two-way references: id_uint <-> table
563 lua_pushvalue(L, i); // ... _R[kMtIdRegKey] {mt} 562 lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] {mt}
564 lua_pushinteger(L, id); // ... _R[kMtIdRegKey] {mt} id 563 lua_pushinteger(L_, id); // ... _R[kMtIdRegKey] {mt} id
565 lua_rawset(L, -3); // ... _R[kMtIdRegKey] 564 lua_rawset(L_, -3); // ... _R[kMtIdRegKey]
566 565
567 lua_pushinteger(L, id); // ... _R[kMtIdRegKey] id 566 lua_pushinteger(L_, id); // ... _R[kMtIdRegKey] id
568 lua_pushvalue(L, i); // ... _R[kMtIdRegKey] id {mt} 567 lua_pushvalue(L_, i); // ... _R[kMtIdRegKey] id {mt}
569 lua_rawset(L, -3); // ... _R[kMtIdRegKey] 568 lua_rawset(L_, -3); // ... _R[kMtIdRegKey]
570 } 569 }
571 lua_pop(L, 1); // ... 570 lua_pop(L_, 1); // ...
572 STACK_CHECK(L, 0); 571 STACK_CHECK(L_, 0);
573 572
574 return id; 573 return id;
575} 574}
@@ -577,25 +576,25 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
577// ################################################################################################# 576// #################################################################################################
578 577
579// function sentinel used to transfer native functions from/to keeper states 578// function sentinel used to transfer native functions from/to keeper states
580[[nodiscard]] static int func_lookup_sentinel(lua_State* L) 579[[nodiscard]] static int func_lookup_sentinel(lua_State* L_)
581{ 580{
582 raise_luaL_error(L, "function lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); 581 raise_luaL_error(L_, "function lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
583} 582}
584 583
585// ################################################################################################# 584// #################################################################################################
586 585
587// function sentinel used to transfer native table from/to keeper states 586// function sentinel used to transfer native table from/to keeper states
588[[nodiscard]] static int table_lookup_sentinel(lua_State* L) 587[[nodiscard]] static int table_lookup_sentinel(lua_State* L_)
589{ 588{
590 raise_luaL_error(L, "table lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); 589 raise_luaL_error(L_, "table lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
591} 590}
592 591
593// ################################################################################################# 592// #################################################################################################
594 593
595// function sentinel used to transfer cloned full userdata from/to keeper states 594// function sentinel used to transfer cloned full userdata from/to keeper states
596[[nodiscard]] static int userdata_clone_sentinel(lua_State* L) 595[[nodiscard]] static int userdata_clone_sentinel(lua_State* L_)
597{ 596{
598 raise_luaL_error(L, "userdata clone sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); 597 raise_luaL_error(L_, "userdata clone sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
599} 598}
600 599
601// ################################################################################################# 600// #################################################################################################
@@ -603,55 +602,55 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
603/* 602/*
604 * retrieve the name of a function/table in the lookup database 603 * retrieve the name of a function/table in the lookup database
605 */ 604 */
606[[nodiscard]] static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char const* upName_, size_t* len_) 605[[nodiscard]] static char const* find_lookup_name(lua_State* L_, int i, LookupMode mode_, char const* upName_, size_t* len_)
607{ 606{
608 DEBUGSPEW_CODE( Universe* const U = universe_get( L)); 607 DEBUGSPEW_CODE( Universe* const U = universe_get( L_));
609 char const* fqn; 608 char const* fqn;
610 LUA_ASSERT(L, lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... 609 LUA_ASSERT(L_, lua_isfunction( L_, i) || lua_istable( L_, i)); // ... v ...
611 STACK_CHECK_START_REL(L, 0); 610 STACK_CHECK_START_REL(L_, 0);
612 STACK_GROW( L, 3); // up to 3 slots are necessary on error 611 STACK_GROW( L_, 3); // up to 3 slots are necessary on error
613 if (mode_ == LookupMode::FromKeeper) 612 if (mode_ == LookupMode::FromKeeper)
614 { 613 {
615 lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! 614 lua_CFunction f = lua_tocfunction( L_, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel!
616 if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) 615 if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel)
617 { 616 {
618 lua_getupvalue( L, i, 1); // ... v ... "f.q.n" 617 lua_getupvalue( L_, i, 1); // ... v ... "f.q.n"
619 } 618 }
620 else 619 else
621 { 620 {
622 // if this is not a sentinel, this is some user-created table we wanted to lookup 621 // if this is not a sentinel, this is some user-created table we wanted to lookup
623 LUA_ASSERT(L, nullptr == f && lua_istable(L, i)); 622 LUA_ASSERT(L_, nullptr == f && lua_istable(L_, i));
624 // push anything that will convert to nullptr string 623 // push anything that will convert to nullptr string
625 lua_pushnil( L); // ... v ... nil 624 lua_pushnil( L_); // ... v ... nil
626 } 625 }
627 } 626 }
628 else 627 else
629 { 628 {
630 // fetch the name from the source state's lookup table 629 // fetch the name from the source state's lookup table
631 kLookupRegKey.pushValue(L); // ... v ... {} 630 kLookupRegKey.pushValue(L_); // ... v ... {}
632 STACK_CHECK( L, 1); 631 STACK_CHECK( L_, 1);
633 LUA_ASSERT(L, lua_istable( L, -1)); 632 LUA_ASSERT(L_, lua_istable( L_, -1));
634 lua_pushvalue( L, i); // ... v ... {} v 633 lua_pushvalue( L_, i); // ... v ... {} v
635 lua_rawget( L, -2); // ... v ... {} "f.q.n" 634 lua_rawget( L_, -2); // ... v ... {} "f.q.n"
636 } 635 }
637 fqn = lua_tolstring( L, -1, len_); 636 fqn = lua_tolstring( L_, -1, len_);
638 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); 637 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn));
639 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database 638 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
640 lua_pop( L, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ... 639 lua_pop( L_, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ...
641 STACK_CHECK( L, 0); 640 STACK_CHECK( L_, 0);
642 if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) 641 if (nullptr == fqn && !lua_istable(L_, i)) // raise an error if we try to send an unknown function (but not for tables)
643 { 642 {
644 char const *from, *typewhat, *what, *gotchaA, *gotchaB; 643 char const *from, *typewhat, *what, *gotchaA, *gotchaB;
645 // try to discover the name of the function we want to send 644 // try to discover the name of the function we want to send
646 lua_getglobal( L, "decoda_name"); // ... v ... decoda_name 645 lua_getglobal( L_, "decoda_name"); // ... v ... decoda_name
647 from = lua_tostring( L, -1); 646 from = lua_tostring( L_, -1);
648 lua_pushcfunction( L, luaG_nameof); // ... v ... decoda_name luaG_nameof 647 lua_pushcfunction( L_, luaG_nameof); // ... v ... decoda_name luaG_nameof
649 lua_pushvalue( L, i); // ... v ... decoda_name luaG_nameof t 648 lua_pushvalue( L_, i); // ... v ... decoda_name luaG_nameof t
650 lua_call( L, 1, 2); // ... v ... decoda_name "type" "name"|nil 649 lua_call( L_, 1, 2); // ... v ... decoda_name "type" "name"|nil
651 typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2); 650 typewhat = (lua_type( L_, -2) == LUA_TSTRING) ? lua_tostring( L_, -2) : luaL_typename( L_, -2);
652 // second return value can be nil if the table was not found 651 // second return value can be nil if the table was not found
653 // probable reason: the function was removed from the source Lua state before Lanes was required. 652 // probable reason: the function was removed from the source Lua state before Lanes was required.
654 if (lua_isnil( L, -1)) 653 if (lua_isnil( L_, -1))
655 { 654 {
656 gotchaA = " referenced by"; 655 gotchaA = " referenced by";
657 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; 656 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)";
@@ -661,13 +660,13 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
661 { 660 {
662 gotchaA = ""; 661 gotchaA = "";
663 gotchaB = ""; 662 gotchaB = "";
664 what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1); 663 what = (lua_type( L_, -1) == LUA_TSTRING) ? lua_tostring( L_, -1) : luaL_typename( L_, -1);
665 } 664 }
666 raise_luaL_error(L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); 665 raise_luaL_error(L_, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB);
667 *len_ = 0; 666 *len_ = 0;
668 return nullptr; 667 return nullptr;
669 } 668 }
670 STACK_CHECK( L, 0); 669 STACK_CHECK( L_, 0);
671 return fqn; 670 return fqn;
672} 671}
673 672
@@ -787,7 +786,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
787/* 786/*
788 * Return some name helping to identify an object 787 * Return some name helping to identify an object
789 */ 788 */
790[[nodiscard]] static int discover_object_name_recur(lua_State* L, int shortest_, int depth_) 789[[nodiscard]] static int discover_object_name_recur(lua_State* L_, int shortest_, int depth_)
791{ 790{
792 int const what = 1; // o "r" {c} {fqn} ... {?} 791 int const what = 1; // o "r" {c} {fqn} ... {?}
793 int const result = 2; 792 int const result = 2;
@@ -798,72 +797,72 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
798 { 797 {
799 return shortest_; 798 return shortest_;
800 } 799 }
801 STACK_GROW(L, 3); 800 STACK_GROW(L_, 3);
802 STACK_CHECK_START_REL(L, 0); 801 STACK_CHECK_START_REL(L_, 0);
803 // stack top contains the table to search in 802 // stack top contains the table to search in
804 lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} 803 lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?}
805 lua_rawget(L, cache); // o "r" {c} {fqn} ... {?} nil/1 804 lua_rawget(L_, cache); // o "r" {c} {fqn} ... {?} nil/1
806 // if table is already visited, we are done 805 // if table is already visited, we are done
807 if (!lua_isnil(L, -1)) 806 if (!lua_isnil(L_, -1))
808 { 807 {
809 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} 808 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?}
810 return shortest_; 809 return shortest_;
811 } 810 }
812 // examined table is not in the cache, add it now 811 // examined table is not in the cache, add it now
813 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} 812 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?}
814 lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} 813 lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?}
815 lua_pushinteger(L, 1); // o "r" {c} {fqn} ... {?} {?} 1 814 lua_pushinteger(L_, 1); // o "r" {c} {fqn} ... {?} {?} 1
816 lua_rawset(L, cache); // o "r" {c} {fqn} ... {?} 815 lua_rawset(L_, cache); // o "r" {c} {fqn} ... {?}
817 // scan table contents 816 // scan table contents
818 lua_pushnil(L); // o "r" {c} {fqn} ... {?} nil 817 lua_pushnil(L_); // o "r" {c} {fqn} ... {?} nil
819 while (lua_next(L, -2)) // o "r" {c} {fqn} ... {?} k v 818 while (lua_next(L_, -2)) // o "r" {c} {fqn} ... {?} k v
820 { 819 {
821 //char const *const strKey = (lua_type(L, -2) == LUA_TSTRING) ? lua_tostring(L, -2) : nullptr; // only for debugging 820 //char const *const strKey = (lua_type(L_, -2) == LUA_TSTRING) ? lua_tostring(L_, -2) : nullptr; // only for debugging
822 //lua_Number const numKey = (lua_type(L, -2) == LUA_TNUMBER) ? lua_tonumber(L, -2) : -6666; // only for debugging 821 //lua_Number const numKey = (lua_type(L_, -2) == LUA_TNUMBER) ? lua_tonumber(L_, -2) : -6666; // only for debugging
823 STACK_CHECK(L, 2); 822 STACK_CHECK(L_, 2);
824 // append key name to fqn stack 823 // append key name to fqn stack
825 ++ depth_; 824 ++ depth_;
826 lua_pushvalue(L, -2); // o "r" {c} {fqn} ... {?} k v k 825 lua_pushvalue(L_, -2); // o "r" {c} {fqn} ... {?} k v k
827 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v 826 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v
828 if (lua_rawequal(L, -1, what)) // is it what we are looking for? 827 if (lua_rawequal(L_, -1, what)) // is it what we are looking for?
829 { 828 {
830 STACK_CHECK(L, 2); 829 STACK_CHECK(L_, 2);
831 // update shortest name 830 // update shortest name
832 if (depth_ < shortest_) 831 if (depth_ < shortest_)
833 { 832 {
834 shortest_ = depth_; 833 shortest_ = depth_;
835 std::ignore = luaG_pushFQN(L, fqn, depth_, nullptr); // o "r" {c} {fqn} ... {?} k v "fqn" 834 std::ignore = luaG_pushFQN(L_, fqn, depth_, nullptr); // o "r" {c} {fqn} ... {?} k v "fqn"
836 lua_replace(L, result); // o "r" {c} {fqn} ... {?} k v 835 lua_replace(L_, result); // o "r" {c} {fqn} ... {?} k v
837 } 836 }
838 // no need to search further at this level 837 // no need to search further at this level
839 lua_pop(L, 2); // o "r" {c} {fqn} ... {?} 838 lua_pop(L_, 2); // o "r" {c} {fqn} ... {?}
840 STACK_CHECK(L, 0); 839 STACK_CHECK(L_, 0);
841 break; 840 break;
842 } 841 }
843 switch (lua_type(L, -1)) // o "r" {c} {fqn} ... {?} k v 842 switch (lua_type(L_, -1)) // o "r" {c} {fqn} ... {?} k v
844 { 843 {
845 default: // nil, boolean, light userdata, number and string aren't identifiable 844 default: // nil, boolean, light userdata, number and string aren't identifiable
846 break; 845 break;
847 846
848 case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} 847 case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {}
849 STACK_CHECK(L, 2); 848 STACK_CHECK(L_, 2);
850 shortest_ = discover_object_name_recur(L, shortest_, depth_); 849 shortest_ = discover_object_name_recur(L_, shortest_, depth_);
851 // search in the table's metatable too 850 // search in the table's metatable too
852 if (lua_getmetatable(L, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} 851 if (lua_getmetatable(L_, -1)) // o "r" {c} {fqn} ... {?} k {} {mt}
853 { 852 {
854 if (lua_istable(L, -1)) 853 if (lua_istable(L_, -1))
855 { 854 {
856 ++ depth_; 855 ++ depth_;
857 lua_pushliteral(L, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" 856 lua_pushliteral(L_, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable"
858 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} 857 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt}
859 shortest_ = discover_object_name_recur(L, shortest_, depth_); 858 shortest_ = discover_object_name_recur(L_, shortest_, depth_);
860 lua_pushnil(L); // o "r" {c} {fqn} ... {?} k {} {mt} nil 859 lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k {} {mt} nil
861 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} 860 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt}
862 -- depth_; 861 -- depth_;
863 } 862 }
864 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k {} 863 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k {}
865 } 864 }
866 STACK_CHECK(L, 2); 865 STACK_CHECK(L_, 2);
867 break; 866 break;
868 867
869 case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T 868 case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T
@@ -871,61 +870,61 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
871 break; 870 break;
872 871
873 case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U 872 case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U
874 STACK_CHECK(L, 2); 873 STACK_CHECK(L_, 2);
875 // search in the object's metatable (some modules are built that way) 874 // search in the object's metatable (some modules are built that way)
876 if (lua_getmetatable(L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} 875 if (lua_getmetatable(L_, -1)) // o "r" {c} {fqn} ... {?} k U {mt}
877 { 876 {
878 if (lua_istable(L, -1)) 877 if (lua_istable(L_, -1))
879 { 878 {
880 ++ depth_; 879 ++ depth_;
881 lua_pushliteral(L, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable" 880 lua_pushliteral(L_, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable"
882 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} 881 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt}
883 shortest_ = discover_object_name_recur(L, shortest_, depth_); 882 shortest_ = discover_object_name_recur(L_, shortest_, depth_);
884 lua_pushnil(L); // o "r" {c} {fqn} ... {?} k U {mt} nil 883 lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k U {mt} nil
885 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} 884 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt}
886 -- depth_; 885 -- depth_;
887 } 886 }
888 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U 887 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U
889 } 888 }
890 STACK_CHECK(L, 2); 889 STACK_CHECK(L_, 2);
891 // search in the object's uservalues 890 // search in the object's uservalues
892 { 891 {
893 int uvi = 1; 892 int uvi = 1;
894 while (lua_getiuservalue(L, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u} 893 while (lua_getiuservalue(L_, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u}
895 { 894 {
896 if (lua_istable(L, -1)) // if it is a table, look inside 895 if (lua_istable(L_, -1)) // if it is a table, look inside
897 { 896 {
898 ++ depth_; 897 ++ depth_;
899 lua_pushliteral(L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" 898 lua_pushliteral(L_, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue"
900 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} 899 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u}
901 shortest_ = discover_object_name_recur(L, shortest_, depth_); 900 shortest_ = discover_object_name_recur(L_, shortest_, depth_);
902 lua_pushnil(L); // o "r" {c} {fqn} ... {?} k v {u} nil 901 lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k v {u} nil
903 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} 902 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u}
904 -- depth_; 903 -- depth_;
905 } 904 }
906 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U 905 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U
907 ++ uvi; 906 ++ uvi;
908 } 907 }
909 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now 908 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
910 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k U 909 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k U
911 } 910 }
912 STACK_CHECK(L, 2); 911 STACK_CHECK(L_, 2);
913 break; 912 break;
914 } 913 }
915 // make ready for next iteration 914 // make ready for next iteration
916 lua_pop(L, 1); // o "r" {c} {fqn} ... {?} k 915 lua_pop(L_, 1); // o "r" {c} {fqn} ... {?} k
917 // remove name from fqn stack 916 // remove name from fqn stack
918 lua_pushnil(L); // o "r" {c} {fqn} ... {?} k nil 917 lua_pushnil(L_); // o "r" {c} {fqn} ... {?} k nil
919 lua_rawseti(L, fqn, depth_); // o "r" {c} {fqn} ... {?} k 918 lua_rawseti(L_, fqn, depth_); // o "r" {c} {fqn} ... {?} k
920 STACK_CHECK(L, 1); 919 STACK_CHECK(L_, 1);
921 -- depth_; 920 -- depth_;
922 } // o "r" {c} {fqn} ... {?} 921 } // o "r" {c} {fqn} ... {?}
923 STACK_CHECK(L, 0); 922 STACK_CHECK(L_, 0);
924 // remove the visited table from the cache, in case a shorter path to the searched object exists 923 // remove the visited table from the cache, in case a shorter path to the searched object exists
925 lua_pushvalue(L, -1); // o "r" {c} {fqn} ... {?} {?} 924 lua_pushvalue(L_, -1); // o "r" {c} {fqn} ... {?} {?}
926 lua_pushnil(L); // o "r" {c} {fqn} ... {?} {?} nil 925 lua_pushnil(L_); // o "r" {c} {fqn} ... {?} {?} nil
927 lua_rawset(L, cache); // o "r" {c} {fqn} ... {?} 926 lua_rawset(L_, cache); // o "r" {c} {fqn} ... {?}
928 STACK_CHECK(L, 0); 927 STACK_CHECK(L_, 0);
929 return shortest_; 928 return shortest_;
930} 929}
931 930
@@ -934,47 +933,47 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
934/* 933/*
935 * "type", "name" = lanes.nameof( o) 934 * "type", "name" = lanes.nameof( o)
936 */ 935 */
937int luaG_nameof( lua_State* L) 936int luaG_nameof( lua_State* L_)
938{ 937{
939 int const what{ lua_gettop(L) }; 938 int const what{ lua_gettop(L_) };
940 if (what > 1) 939 if (what > 1)
941 { 940 {
942 raise_luaL_argerror( L, what, "too many arguments."); 941 raise_luaL_argerror( L_, what, "too many arguments.");
943 } 942 }
944 943
945 // nil, boolean, light userdata, number and string aren't identifiable 944 // nil, boolean, light userdata, number and string aren't identifiable
946 if (lua_type( L, 1) < LUA_TTABLE) 945 if (lua_type( L_, 1) < LUA_TTABLE)
947 { 946 {
948 lua_pushstring( L, luaL_typename( L, 1)); // o "type" 947 lua_pushstring( L_, luaL_typename( L_, 1)); // o "type"
949 lua_insert( L, -2); // "type" o 948 lua_insert( L_, -2); // "type" o
950 return 2; 949 return 2;
951 } 950 }
952 951
953 STACK_GROW( L, 4); 952 STACK_GROW( L_, 4);
954 STACK_CHECK_START_REL(L, 0); 953 STACK_CHECK_START_REL(L_, 0);
955 // this slot will contain the shortest name we found when we are done 954 // this slot will contain the shortest name we found when we are done
956 lua_pushnil( L); // o nil 955 lua_pushnil( L_); // o nil
957 // push a cache that will contain all already visited tables 956 // push a cache that will contain all already visited tables
958 lua_newtable( L); // o nil {c} 957 lua_newtable( L_); // o nil {c}
959 // push a table whose contents are strings that, when concatenated, produce unique name 958 // push a table whose contents are strings that, when concatenated, produce unique name
960 lua_newtable( L); // o nil {c} {fqn} 959 lua_newtable( L_); // o nil {c} {fqn}
961 lua_pushliteral( L, "_G"); // o nil {c} {fqn} "_G" 960 lua_pushliteral( L_, "_G"); // o nil {c} {fqn} "_G"
962 lua_rawseti( L, -2, 1); // o nil {c} {fqn} 961 lua_rawseti( L_, -2, 1); // o nil {c} {fqn}
963 // this is where we start the search 962 // this is where we start the search
964 lua_pushglobaltable( L); // o nil {c} {fqn} _G 963 lua_pushglobaltable( L_); // o nil {c} {fqn} _G
965 (void) discover_object_name_recur( L, 6666, 1); 964 (void) discover_object_name_recur( L_, 6666, 1);
966 if (lua_isnil( L, 2)) // try again with registry, just in case... 965 if (lua_isnil( L_, 2)) // try again with registry, just in case...
967 { 966 {
968 lua_pop( L, 1); // o nil {c} {fqn} 967 lua_pop( L_, 1); // o nil {c} {fqn}
969 lua_pushliteral( L, "_R"); // o nil {c} {fqn} "_R" 968 lua_pushliteral( L_, "_R"); // o nil {c} {fqn} "_R"
970 lua_rawseti( L, -2, 1); // o nil {c} {fqn} 969 lua_rawseti( L_, -2, 1); // o nil {c} {fqn}
971 lua_pushvalue( L, LUA_REGISTRYINDEX); // o nil {c} {fqn} _R 970 lua_pushvalue( L_, LUA_REGISTRYINDEX); // o nil {c} {fqn} _R
972 (void) discover_object_name_recur( L, 6666, 1); 971 (void) discover_object_name_recur( L_, 6666, 1);
973 } 972 }
974 lua_pop( L, 3); // o "result" 973 lua_pop( L_, 3); // o "result"
975 STACK_CHECK( L, 1); 974 STACK_CHECK( L_, 1);
976 lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" 975 lua_pushstring( L_, luaL_typename( L_, 1)); // o "result" "type"
977 lua_replace( L, -3); // "type" "result" 976 lua_replace( L_, -3); // "type" "result"
978 return 2; 977 return 2;
979} 978}
980 979
@@ -1090,12 +1089,12 @@ static char const* vt_names[] =
1090// we have to do it that way because we can't unbalance the stack between buffer operations 1089// we have to do it that way because we can't unbalance the stack between buffer operations
1091// namely, this means we can't push a function on top of the stack *after* we initialize the buffer! 1090// namely, this means we can't push a function on top of the stack *after* we initialize the buffer!
1092// luckily, this also works with earlier Lua versions 1091// luckily, this also works with earlier Lua versions
1093[[nodiscard]] static int buf_writer(lua_State* L, void const* b, size_t size, void* ud) 1092[[nodiscard]] static int buf_writer(lua_State* L_, void const* b, size_t size, void* ud)
1094{ 1093{
1095 luaL_Buffer* B = (luaL_Buffer*) ud; 1094 luaL_Buffer* B = (luaL_Buffer*) ud;
1096 if (!B->L) 1095 if (!B->L)
1097 { 1096 {
1098 luaL_buffinit( L, B); 1097 luaL_buffinit( L_, B);
1099 } 1098 }
1100 luaL_addlstring( B, (char const*) b, size); 1099 luaL_addlstring( B, (char const*) b, size);
1101 return 0; 1100 return 0;
diff --git a/src/tools.h b/src/tools.h
index f83a01c..b58ae00 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -8,8 +8,8 @@ class Universe;
8 8
9// ################################################################################################# 9// #################################################################################################
10 10
11void push_registry_subtable_mode(lua_State* L, RegistryUniqueKey key_, const char* mode_); 11void push_registry_subtable_mode(lua_State* L_, RegistryUniqueKey key_, const char* mode_);
12void push_registry_subtable(lua_State* L, RegistryUniqueKey key_); 12void push_registry_subtable(lua_State* L_, RegistryUniqueKey key_);
13 13
14enum class VT 14enum class VT
15{ 15{
@@ -77,10 +77,10 @@ class InterCopyContext
77 77
78// ################################################################################################# 78// #################################################################################################
79 79
80[[nodiscard]] int luaG_nameof(lua_State* L); 80[[nodiscard]] int luaG_nameof(lua_State* L_);
81 81
82void populate_func_lookup_table(lua_State* L, int _i, char const* _name); 82void populate_func_lookup_table(lua_State* L_, int _i, char const* _name);
83void initialize_allocator_function(Universe* U, lua_State* L); 83void initialize_allocator_function(Universe* U, lua_State* L_);
84 84
85// ################################################################################################# 85// #################################################################################################
86 86
diff --git a/src/universe.cpp b/src/universe.cpp
index 4eca0c9..062d552 100644
--- a/src/universe.cpp
+++ b/src/universe.cpp
@@ -73,34 +73,34 @@ Universe::Universe()
73// ################################################################################################# 73// #################################################################################################
74 74
75// only called from the master state 75// only called from the master state
76Universe* universe_create(lua_State* L) 76Universe* universe_create(lua_State* L_)
77{ 77{
78 LUA_ASSERT(L, universe_get(L) == nullptr); 78 LUA_ASSERT(L_, universe_get(L_) == nullptr);
79 Universe* const U{ lua_newuserdatauv<Universe>(L, 0) }; // universe 79 Universe* const U{ lua_newuserdatauv<Universe>(L_, 0) }; // universe
80 U->Universe::Universe(); 80 U->Universe::Universe();
81 STACK_CHECK_START_REL(L, 1); 81 STACK_CHECK_START_REL(L_, 1);
82 kUniverseFullRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 82 kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); });
83 kUniverseLightRegKey.setValue(L, [U](lua_State* L) { lua_pushlightuserdata(L, U); }); 83 kUniverseLightRegKey.setValue(L_, [U](lua_State* L_) { lua_pushlightuserdata(L_, U); });
84 STACK_CHECK(L, 1); 84 STACK_CHECK(L_, 1);
85 return U; 85 return U;
86} 86}
87 87
88// ################################################################################################# 88// #################################################################################################
89 89
90void universe_store(lua_State* L, Universe* U) 90void universe_store(lua_State* L_, Universe* U)
91{ 91{
92 LUA_ASSERT(L, !U || universe_get(L) == nullptr); 92 LUA_ASSERT(L_, !U || universe_get(L_) == nullptr);
93 STACK_CHECK_START_REL(L, 0); 93 STACK_CHECK_START_REL(L_, 0);
94 kUniverseLightRegKey.setValue(L, [U](lua_State* L) { U ? lua_pushlightuserdata(L, U) : lua_pushnil(L); }); 94 kUniverseLightRegKey.setValue(L_, [U](lua_State* L_) { U ? lua_pushlightuserdata(L_, U) : lua_pushnil(L_); });
95 STACK_CHECK(L, 0); 95 STACK_CHECK(L_, 0);
96} 96}
97 97
98// ################################################################################################# 98// #################################################################################################
99 99
100Universe* universe_get(lua_State* L) 100Universe* universe_get(lua_State* L_)
101{ 101{
102 STACK_CHECK_START_REL(L, 0); 102 STACK_CHECK_START_REL(L_, 0);
103 Universe* const universe{ kUniverseLightRegKey.readLightUserDataValue<Universe>(L) }; 103 Universe* const universe{ kUniverseLightRegKey.readLightUserDataValue<Universe>(L_) };
104 STACK_CHECK(L, 0); 104 STACK_CHECK(L_, 0);
105 return universe; 105 return universe;
106} 106}
diff --git a/src/universe.h b/src/universe.h
index 128c4d9..2fd487e 100644
--- a/src/universe.h
+++ b/src/universe.h
@@ -34,7 +34,7 @@ class AllocatorDefinition
34 void* m_allocUD{ nullptr }; 34 void* m_allocUD{ nullptr };
35 35
36 [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state 36 [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state
37 [[nodiscard]] static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv(L, size_, 0); } 37 [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, size_, 0); }
38 // always embedded somewhere else or "in-place constructed" as a full userdata 38 // always embedded somewhere else or "in-place constructed" as a full userdata
39 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception 39 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
40 static void operator delete([[maybe_unused]] void* p_, lua_State* L_) { LUA_ASSERT(L_, !"should never be called"); } 40 static void operator delete([[maybe_unused]] void* p_, lua_State* L_) { LUA_ASSERT(L_, !"should never be called"); }
@@ -50,9 +50,9 @@ class AllocatorDefinition
50 AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; 50 AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default;
51 AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; 51 AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default;
52 52
53 void initFrom(lua_State* L) 53 void initFrom(lua_State* L_)
54 { 54 {
55 m_allocF = lua_getallocf(L, &m_allocUD); 55 m_allocF = lua_getallocf(L_, &m_allocUD);
56 } 56 }
57 57
58 void* lua_alloc(void* ptr_, size_t osize_, size_t nsize_) 58 void* lua_alloc(void* ptr_, size_t osize_, size_t nsize_)
@@ -89,25 +89,25 @@ class ProtectedAllocator
89 89
90 public: 90 public:
91 // we are not like our base class: we can't be created inside a full userdata (or we would have to install a metatable and __gc handler to destroy ourselves properly) 91 // we are not like our base class: we can't be created inside a full userdata (or we would have to install a metatable and __gc handler to destroy ourselves properly)
92 [[nodiscard]] static void* operator new(size_t size_, lua_State* L) noexcept = delete; 92 [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept = delete;
93 static void operator delete(void* p_, lua_State* L) = delete; 93 static void operator delete(void* p_, lua_State* L_) = delete;
94 94
95 AllocatorDefinition makeDefinition() 95 AllocatorDefinition makeDefinition()
96 { 96 {
97 return AllocatorDefinition{ protected_lua_Alloc, this }; 97 return AllocatorDefinition{ protected_lua_Alloc, this };
98 } 98 }
99 99
100 void installIn(lua_State* L) 100 void installIn(lua_State* L_)
101 { 101 {
102 lua_setallocf(L, protected_lua_Alloc, this); 102 lua_setallocf(L_, protected_lua_Alloc, this);
103 } 103 }
104 104
105 void removeFrom(lua_State* L) 105 void removeFrom(lua_State* L_)
106 { 106 {
107 // remove the protected allocator, if any 107 // remove the protected allocator, if any
108 if (m_allocF != nullptr) { 108 if (m_allocF != nullptr) {
109 // install the non-protected allocator 109 // install the non-protected allocator
110 lua_setallocf(L, m_allocF, m_allocUD); 110 lua_setallocf(L_, m_allocF, m_allocUD);
111 } 111 }
112 } 112 }
113}; 113};
@@ -182,9 +182,9 @@ class Universe
182 182
183// ################################################################################################# 183// #################################################################################################
184 184
185[[nodiscard]] Universe* universe_get(lua_State* L); 185[[nodiscard]] Universe* universe_get(lua_State* L_);
186[[nodiscard]] Universe* universe_create(lua_State* L); 186[[nodiscard]] Universe* universe_create(lua_State* L_);
187void universe_store(lua_State* L, Universe* U); 187void universe_store(lua_State* L_, Universe* U);
188 188
189// ################################################################################################# 189// #################################################################################################
190 190