aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deep_test/deep_test.cpp8
-rw-r--r--docs/index.html12
-rw-r--r--src/cancel.cpp49
-rw-r--r--src/cancel.h16
-rw-r--r--src/deep.cpp40
-rw-r--r--src/deep.h18
-rw-r--r--src/keeper.cpp16
-rw-r--r--src/keeper.h2
-rw-r--r--src/lanes.cpp86
-rw-r--r--src/linda.cpp16
-rw-r--r--src/state.cpp6
-rw-r--r--src/state.h16
-rw-r--r--src/tools.cpp139
-rw-r--r--src/tools.h10
-rw-r--r--src/universe.h6
15 files changed, 244 insertions, 196 deletions
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp
index d7ecd33..7c8180f 100644
--- a/deep_test/deep_test.cpp
+++ b/deep_test/deep_test.cpp
@@ -19,26 +19,26 @@ static void* deep_test_id( lua_State* L, DeepOp op_)
19{ 19{
20 switch( op_) 20 switch( op_)
21 { 21 {
22 case eDO_new: 22 case DeepOp::New:
23 { 23 {
24 MyDeepUserdata* deep_test = new MyDeepUserdata; 24 MyDeepUserdata* deep_test = new MyDeepUserdata;
25 return deep_test; 25 return deep_test;
26 } 26 }
27 27
28 case eDO_delete: 28 case DeepOp::Delete:
29 { 29 {
30 MyDeepUserdata* deep_test = static_cast<MyDeepUserdata*>(lua_touserdata( L, 1)); 30 MyDeepUserdata* deep_test = static_cast<MyDeepUserdata*>(lua_touserdata( L, 1));
31 delete deep_test; 31 delete deep_test;
32 return nullptr; 32 return nullptr;
33 } 33 }
34 34
35 case eDO_metatable: 35 case DeepOp::Metatable:
36 { 36 {
37 luaL_getmetatable( L, "deep"); // mt 37 luaL_getmetatable( L, "deep"); // mt
38 return nullptr; 38 return nullptr;
39 } 39 }
40 40
41 case eDO_module: 41 case DeepOp::Module:
42 return (void*)"deep_test"; 42 return (void*)"deep_test";
43 43
44 default: 44 default:
diff --git a/docs/index.html b/docs/index.html
index f8124c7..24fa4ef 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1669,10 +1669,10 @@ int luaD_new_clonable( lua_State* L)
1669 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, DeepOp op_);</pre></td></tr></table> 1669 <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, DeepOp op_);</pre></td></tr></table>
1670 <tt>op_</tt> can be one of: 1670 <tt>op_</tt> can be one of:
1671 <ul> 1671 <ul>
1672 <li><tt>eDO_new</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li> 1672 <li><tt>DeepOp::New</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li>
1673 <li><tt>eDO_delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> 1673 <li><tt>DeepOp::Delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li>
1674 <li><tt>eDO_metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>eDO_metatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li> 1674 <li><tt>DeepOp::Metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>DeepOp::Metatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li>
1675 <li><tt>eDO_module</tt>: requests the name of the module that exports the idfunc, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the idfunc pointer is still held.</li> 1675 <li><tt>DeepOp::Module</tt>: requests the name of the module that exports the idfunc, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the idfunc pointer is still held.</li>
1676 </ul> 1676 </ul>
1677 Take a look at <tt>linda_id</tt> in <tt>lanes.cpp</tt> or <tt>deep_test_id</tt> in <tt>deep_test.cpp</tt>. 1677 Take a look at <tt>linda_id</tt> in <tt>lanes.cpp</tt> or <tt>deep_test_id</tt> in <tt>deep_test.cpp</tt>.
1678 </li> 1678 </li>
@@ -1686,13 +1686,13 @@ int luaD_new_clonable( lua_State* L)
1686</p> 1686</p>
1687 1687
1688<p> 1688<p>
1689 Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(eDO_delete)</tt> and aren't considered by reference counting. The rationale is the following: 1689 Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(DeepOp::Delete)</tt> and aren't considered by reference counting. The rationale is the following:
1690 <br /> 1690 <br />
1691 If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0. 1691 If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0.
1692 <br /> 1692 <br />
1693 OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>idfunc()</tt> is never called from a keeper state. 1693 OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>idfunc()</tt> is never called from a keeper state.
1694 <br /> 1694 <br />
1695 Therefore, Lanes can just call <tt>idfunc(eDO_delete)</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in keeper states now hold stale pointers. 1695 Therefore, Lanes can just call <tt>idfunc(DeepOp::Delete)</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in keeper states now hold stale pointers.
1696</p> 1696</p>
1697 1697
1698<p> 1698<p>
diff --git a/src/cancel.cpp b/src/cancel.cpp
index 07c316a..4667f07 100644
--- a/src/cancel.cpp
+++ b/src/cancel.cpp
@@ -189,7 +189,7 @@ CancelResult thread_cancel(lua_State* L, Lane* lane_, CancelOp op_, double secs_
189 189
190 // signal the linda the wake up the thread so that it can react to the cancel query 190 // signal the linda the wake up the thread so that it can react to the cancel query
191 // let us hope we never land here with a pointer on a linda that has been destroyed... 191 // let us hope we never land here with a pointer on a linda that has been destroyed...
192 if (op_ == CO_Soft) 192 if (op_ == CancelOp::Soft)
193 { 193 {
194 return thread_cancel_soft(lane_, secs_, force_); 194 return thread_cancel_soft(lane_, secs_, force_);
195 } 195 }
@@ -203,45 +203,46 @@ CancelResult thread_cancel(lua_State* L, Lane* lane_, CancelOp op_, double secs_
203// > 0: the mask 203// > 0: the mask
204// = 0: soft 204// = 0: soft
205// < 0: hard 205// < 0: hard
206static CancelOp which_op( lua_State* L, int idx_) 206static CancelOp which_op(lua_State* L, int idx_)
207{ 207{
208 if( lua_type( L, idx_) == LUA_TSTRING) 208 if (lua_type(L, idx_) == LUA_TSTRING)
209 { 209 {
210 CancelOp op = CO_Invalid; 210 CancelOp op{ CancelOp::Invalid };
211 char const* str = lua_tostring( L, idx_); 211 char const* str = lua_tostring(L, idx_);
212 if( strcmp( str, "soft") == 0) 212 if (strcmp(str, "hard") == 0)
213 { 213 {
214 op = CO_Soft; 214 op = CancelOp::Hard;
215 } 215 }
216 else if( strcmp( str, "count") == 0) 216 else if (strcmp(str, "soft") == 0)
217 { 217 {
218 op = CO_Count; 218 op = CancelOp::Soft;
219 } 219 }
220 else if( strcmp( str, "line") == 0) 220 else if (strcmp(str, "call") == 0)
221 { 221 {
222 op = CO_Line; 222 op = CancelOp::MaskCall;
223 } 223 }
224 else if( strcmp( str, "call") == 0) 224 else if (strcmp(str, "ret") == 0)
225 { 225 {
226 op = CO_Call; 226 op = CancelOp::MaskRet;
227 } 227 }
228 else if( strcmp( str, "ret") == 0) 228 else if (strcmp(str, "line") == 0)
229 { 229 {
230 op = CO_Ret; 230 op = CancelOp::MaskLine;
231 } 231 }
232 else if( strcmp( str, "hard") == 0) 232 else if (strcmp(str, "count") == 0)
233 { 233 {
234 op = CO_Hard; 234 op = CancelOp::MaskCount;
235 } 235 }
236 lua_remove( L, idx_); // argument is processed, remove it 236 lua_remove(L, idx_); // argument is processed, remove it
237 if( op == CO_Invalid) 237 if (op == CancelOp::Invalid)
238 { 238 {
239 std::ignore = luaL_error( L, "invalid hook option %s", str); 239 std::ignore = luaL_error(L, "invalid hook option %s", str);
240 } 240 }
241 return op; 241 return op;
242 } 242 }
243 return CO_Hard; 243 return CancelOp::Hard;
244} 244}
245
245// ################################################################################################ 246// ################################################################################################
246 247
247// bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, force [, forcekill_timeout]]) 248// bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, force [, forcekill_timeout]])
@@ -250,15 +251,15 @@ LUAG_FUNC(thread_cancel)
250 Lane* const lane{ lua_toLane(L, 1) }; 251 Lane* const lane{ lua_toLane(L, 1) };
251 CancelOp const op{ which_op(L, 2) }; // this removes the op string from the stack 252 CancelOp const op{ which_op(L, 2) }; // this removes the op string from the stack
252 253
253 if (op > 0) // hook is requested 254 if (static_cast<int>(op) > static_cast<int>(CancelOp::Soft)) // hook is requested
254 { 255 {
255 int hook_count = (int) lua_tointeger(L, 2); 256 int const hook_count{ static_cast<int>(lua_tointeger(L, 2)) };
256 lua_remove(L, 2); // argument is processed, remove it 257 lua_remove(L, 2); // argument is processed, remove it
257 if (hook_count < 1) 258 if (hook_count < 1)
258 { 259 {
259 return luaL_error(L, "hook count cannot be < 1"); 260 return luaL_error(L, "hook count cannot be < 1");
260 } 261 }
261 lua_sethook(lane->L, cancel_hook, op, hook_count); 262 lua_sethook(lane->L, cancel_hook, static_cast<int>(op), hook_count);
262 } 263 }
263 264
264 double secs{ 0.0 }; 265 double secs{ 0.0 };
diff --git a/src/cancel.h b/src/cancel.h
index 0c1de14..884e193 100644
--- a/src/cancel.h
+++ b/src/cancel.h
@@ -34,15 +34,15 @@ enum class CancelResult
34 Killed 34 Killed
35}; 35};
36 36
37enum CancelOp 37enum class CancelOp
38{ 38{
39 CO_Invalid = -2, 39 Invalid = -2,
40 CO_Hard = -1, 40 Hard = -1,
41 CO_Soft = 0, 41 Soft = 0,
42 CO_Count = LUA_MASKCOUNT, 42 MaskCall = LUA_MASKCALL,
43 CO_Line = LUA_MASKLINE, 43 MaskRet = LUA_MASKRET,
44 CO_Call = LUA_MASKCALL, 44 MaskLine = LUA_MASKLINE,
45 CO_Ret = LUA_MASKRET, 45 MaskCount = LUA_MASKCOUNT,
46}; 46};
47 47
48// crc64/we of string "CANCEL_ERROR" generated at http://www.nitrxgen.net/hashgen/ 48// crc64/we of string "CANCEL_ERROR" generated at http://www.nitrxgen.net/hashgen/
diff --git a/src/deep.cpp b/src/deep.cpp
index 290e5ff..ac2905e 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -113,7 +113,7 @@ static void get_deep_lookup( lua_State* L)
113static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mode_) 113static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mode_)
114{ 114{
115 // when looking inside a keeper, we are 100% sure the object is a deep userdata 115 // when looking inside a keeper, we are 100% sure the object is a deep userdata
116 if( mode_ == eLM_FromKeeper) 116 if (mode_ == LookupMode::FromKeeper)
117 { 117 {
118 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, index) }; 118 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, index) };
119 // we can (and must) cast and fetch the internally stored idfunc 119 // we can (and must) cast and fetch the internally stored idfunc
@@ -149,7 +149,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_)
149 STACK_CHECK_START_REL(L, 0); 149 STACK_CHECK_START_REL(L, 0);
150 // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup 150 // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup
151 lua_pushlightuserdata( L, prelude_); 151 lua_pushlightuserdata( L, prelude_);
152 prelude_->idfunc( L, eDO_delete); 152 prelude_->idfunc( L, DeepOp::Delete);
153 lua_pop(L, 1); 153 lua_pop(L, 1);
154 STACK_CHECK(L, 0); 154 STACK_CHECK(L, 0);
155} 155}
@@ -186,7 +186,7 @@ static int deep_userdata_gc( lua_State* L)
186 // top was set to 0, then userdata was pushed. "delete" might want to pop the userdata (we don't care), but should not push anything! 186 // top was set to 0, then userdata was pushed. "delete" might want to pop the userdata (we don't care), but should not push anything!
187 if ( lua_gettop( L) > 1) 187 if ( lua_gettop( L) > 1)
188 { 188 {
189 return luaL_error( L, "Bad idfunc(eDO_delete): should not push anything"); 189 return luaL_error( L, "Bad idfunc(DeepOp::Delete): should not push anything");
190 } 190 }
191 } 191 }
192 *proxy = nullptr; // make sure we don't use it any more, just in case 192 *proxy = nullptr; // make sure we don't use it any more, just in case
@@ -197,7 +197,7 @@ static int deep_userdata_gc( lua_State* L)
197/* 197/*
198 * Push a proxy userdata on the stack. 198 * Push a proxy userdata on the stack.
199 * returns nullptr if ok, else some error string related to bad idfunc behavior or module require problem 199 * returns nullptr if ok, else some error string related to bad idfunc behavior or module require problem
200 * (error cannot happen with mode_ == eLM_ToKeeper) 200 * (error cannot happen with mode_ == LookupMode::ToKeeper)
201 * 201 *
202 * Initializes necessary structures if it's the first time 'idfunc' is being 202 * Initializes necessary structures if it's the first time 'idfunc' is being
203 * used in this Lua state (metatable, registring it). Otherwise, increments the 203 * used in this Lua state (metatable, registring it). Otherwise, increments the
@@ -238,9 +238,9 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
238 int oldtop = lua_gettop( L); // DPC proxy nil 238 int oldtop = lua_gettop( L); // DPC proxy nil
239 lua_pop( L, 1); // DPC proxy 239 lua_pop( L, 1); // DPC proxy
240 // 1 - make one and register it 240 // 1 - make one and register it
241 if( mode_ != eLM_ToKeeper) 241 if (mode_ != LookupMode::ToKeeper)
242 { 242 {
243 (void) prelude->idfunc( L, eDO_metatable); // DPC proxy metatable 243 (void) prelude->idfunc( L, DeepOp::Metatable); // DPC proxy metatable
244 if( lua_gettop( L) - oldtop != 0 || !lua_istable( L, -1)) 244 if( lua_gettop( L) - oldtop != 0 || !lua_istable( L, -1))
245 { 245 {
246 lua_settop( L, oldtop); // DPC proxy X 246 lua_settop( L, oldtop); // DPC proxy X
@@ -278,7 +278,7 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
278 // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc 278 // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc
279 { 279 {
280 int oldtop_module = lua_gettop( L); 280 int oldtop_module = lua_gettop( L);
281 modname = (char const*) prelude->idfunc( L, eDO_module); // DPC proxy metatable 281 modname = (char const*) prelude->idfunc( L, DeepOp::Module); // DPC proxy metatable
282 // make sure the function pushed nothing on the stack! 282 // make sure the function pushed nothing on the stack!
283 if( lua_gettop( L) - oldtop_module != 0) 283 if( lua_gettop( L) - oldtop_module != 0)
284 { 284 {
@@ -358,9 +358,9 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
358* 358*
359* 'idfunc' must fulfill the following features: 359* 'idfunc' must fulfill the following features:
360* 360*
361* lightuserdata = idfunc( eDO_new [, ...] ) -- creates a new deep data instance 361* lightuserdata = idfunc( DeepOp::New [, ...] ) -- creates a new deep data instance
362* void = idfunc( eDO_delete, lightuserdata ) -- releases a deep data instance 362* void = idfunc( DeepOp::Delete, lightuserdata ) -- releases a deep data instance
363* tbl = idfunc( eDO_metatable ) -- gives metatable for userdata proxies 363* tbl = idfunc( DeepOp::Metatable ) -- gives metatable for userdata proxies
364* 364*
365* Reference counting and true userdata proxying are taken care of for the 365* Reference counting and true userdata proxying are taken care of for the
366* actual data type. 366* actual data type.
@@ -375,18 +375,18 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_)
375 STACK_GROW( L, 1); 375 STACK_GROW( L, 1);
376 STACK_CHECK_START_REL(L, 0); 376 STACK_CHECK_START_REL(L, 0);
377 int const oldtop{ lua_gettop(L) }; 377 int const oldtop{ lua_gettop(L) };
378 DeepPrelude* const prelude{ static_cast<DeepPrelude*>(idfunc(L, eDO_new)) }; 378 DeepPrelude* const prelude{ static_cast<DeepPrelude*>(idfunc(L, DeepOp::New)) };
379 if (prelude == nullptr) 379 if (prelude == nullptr)
380 { 380 {
381 return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); 381 return luaL_error( L, "idfunc(DeepOp::New) failed to create deep userdata (out of memory)");
382 } 382 }
383 383
384 if( prelude->magic != DEEP_VERSION) 384 if( prelude->magic != DEEP_VERSION)
385 { 385 {
386 // just in case, don't leak the newly allocated deep userdata object 386 // just in case, don't leak the newly allocated deep userdata object
387 lua_pushlightuserdata( L, prelude); 387 lua_pushlightuserdata( L, prelude);
388 idfunc( L, eDO_delete); 388 idfunc( L, DeepOp::Delete);
389 return luaL_error( L, "Bad idfunc(eDO_new): DEEP_VERSION is incorrect, rebuild your implementation with the latest deep implementation"); 389 return luaL_error( L, "Bad idfunc(DeepOp::New): DEEP_VERSION is incorrect, rebuild your implementation with the latest deep implementation");
390 } 390 }
391 391
392 ASSERT_L(prelude->m_refcount.load(std::memory_order_relaxed) == 0); // 'push_deep_proxy' will lift it to 1 392 ASSERT_L(prelude->m_refcount.load(std::memory_order_relaxed) == 0); // 'push_deep_proxy' will lift it to 1
@@ -396,11 +396,11 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_)
396 { 396 {
397 // just in case, don't leak the newly allocated deep userdata object 397 // just in case, don't leak the newly allocated deep userdata object
398 lua_pushlightuserdata( L, prelude); 398 lua_pushlightuserdata( L, prelude);
399 idfunc( L, eDO_delete); 399 idfunc( L, DeepOp::Delete);
400 return luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack"); 400 return luaL_error( L, "Bad idfunc(DeepOp::New): should not push anything on the stack");
401 } 401 }
402 402
403 char const* const errmsg{ push_deep_proxy(L, prelude, nuv_, eLM_LaneBody) }; // proxy 403 char const* const errmsg{ push_deep_proxy(L, prelude, nuv_, LookupMode::LaneBody) }; // proxy
404 if (errmsg != nullptr) 404 if (errmsg != nullptr)
405 { 405 {
406 return luaL_error( L, errmsg); 406 return luaL_error( L, errmsg);
@@ -420,7 +420,7 @@ DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index)
420{ 420{
421 STACK_CHECK_START_REL(L, 0); 421 STACK_CHECK_START_REL(L, 0);
422 // ensure it is actually a deep userdata 422 // ensure it is actually a deep userdata
423 if( get_idfunc( L, index, eLM_LaneBody) != idfunc) 423 if (get_idfunc(L, index, LookupMode::LaneBody) != idfunc)
424 { 424 {
425 return nullptr; // no metatable, or wrong kind 425 return nullptr; // no metatable, or wrong kind
426 } 426 }
@@ -466,7 +466,7 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L
466 int const clone_i = lua_gettop( L2); 466 int const clone_i = lua_gettop( L2);
467 while( nuv) 467 while( nuv)
468 { 468 {
469 inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // u uv 469 inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT::NORMAL, mode_, upName_); // u uv
470 lua_pop( L, 1); // ... u [uv]* 470 lua_pop( L, 1); // ... u [uv]*
471 // this pops the value from the stack 471 // this pops the value from the stack
472 lua_setiuservalue( L2, clone_i, nuv); // u 472 lua_setiuservalue( L2, clone_i, nuv); // u
@@ -480,7 +480,7 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L
480 if (errmsg != nullptr) 480 if (errmsg != nullptr)
481 { 481 {
482 // raise the error in the proper state (not the keeper) 482 // raise the error in the proper state (not the keeper)
483 lua_State* const errL { (mode_ == eLM_FromKeeper) ? L2 : L }; 483 lua_State* const errL{ (mode_ == LookupMode::FromKeeper) ? L2 : L };
484 std::ignore = luaL_error(errL, errmsg); 484 std::ignore = luaL_error(errL, errmsg);
485 } 485 }
486 return true; 486 return true;
diff --git a/src/deep.h b/src/deep.h
index 2983427..1799cf0 100644
--- a/src/deep.h
+++ b/src/deep.h
@@ -21,19 +21,19 @@ extern "C" {
21// forwards 21// forwards
22struct Universe; 22struct Universe;
23 23
24enum LookupMode 24enum class LookupMode
25{ 25{
26 eLM_LaneBody, // send the lane body directly from the source to the destination lane 26 LaneBody, // send the lane body directly from the source to the destination lane
27 eLM_ToKeeper, // send a function from a lane to a keeper state 27 ToKeeper, // send a function from a lane to a keeper state
28 eLM_FromKeeper // send a function from a keeper state to a lane 28 FromKeeper // send a function from a keeper state to a lane
29}; 29};
30 30
31enum DeepOp 31enum class DeepOp
32{ 32{
33 eDO_new, 33 New,
34 eDO_delete, 34 Delete,
35 eDO_metatable, 35 Metatable,
36 eDO_module, 36 Module,
37}; 37};
38 38
39using luaG_IdFunction = void*(*)( lua_State* L, DeepOp op_); 39using luaG_IdFunction = void*(*)( lua_State* L, DeepOp op_);
diff --git a/src/keeper.cpp b/src/keeper.cpp
index aab7abe..8f762e5 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -234,10 +234,10 @@ int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, uintptr_t m
234 { 234 {
235 keeper_fifo* fifo = prepare_fifo_access(KL, -1); // storage key fifotbl 235 keeper_fifo* fifo = prepare_fifo_access(KL, -1); // storage key fifotbl
236 lua_pushvalue(KL, -2); // storage key fifotbl key 236 lua_pushvalue(KL, -2); // storage key fifotbl key
237 luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key fifotbl // out key 237 luaG_inter_move(U, KL, L, 1, LookupMode::FromKeeper); // storage key fifotbl // out key
238 STACK_CHECK(L, 2); 238 STACK_CHECK(L, 2);
239 lua_newtable(L); // out key keyout 239 lua_newtable(L); // out key keyout
240 luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key // out key keyout fifotbl 240 luaG_inter_move(U, KL, L, 1, LookupMode::FromKeeper); // storage key // out key keyout fifotbl
241 lua_pushinteger(L, fifo->first); // out key keyout fifotbl first 241 lua_pushinteger(L, fifo->first); // out key keyout fifotbl first
242 STACK_CHECK(L, 5); 242 STACK_CHECK(L, 5);
243 lua_setfield(L, -3, "first"); // out key keyout fifotbl 243 lua_setfield(L, -3, "first"); // out key keyout fifotbl
@@ -703,8 +703,8 @@ void init_keepers(Universe* U, lua_State* L)
703 lua_getglobal(L, "package"); // "..." keepersUD package 703 lua_getglobal(L, "package"); // "..." keepersUD package
704 if (!lua_isnil(L, -1)) 704 if (!lua_isnil(L, -1))
705 { 705 {
706 // when copying with mode eLM_ToKeeper, error message is pushed at the top of the stack, not raised immediately 706 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately
707 if (luaG_inter_copy_package(U, L, K, -1, eLM_ToKeeper)) 707 if (luaG_inter_copy_package(U, L, K, -1, LookupMode::ToKeeper))
708 { 708 {
709 // if something went wrong, the error message is at the top of the stack 709 // if something went wrong, the error message is at the top of the stack
710 lua_remove(L, -2); // error_msg 710 lua_remove(L, -2); // error_msg
@@ -717,7 +717,7 @@ void init_keepers(Universe* U, lua_State* L)
717 // attempt to call on_state_create(), if we have one and it is a C function 717 // attempt to call on_state_create(), if we have one and it is a C function
718 // (only support a C function because we can't transfer executable Lua code in keepers) 718 // (only support a C function because we can't transfer executable Lua code in keepers)
719 // will raise an error in L in case of problem 719 // will raise an error in L in case of problem
720 call_on_state_create(U, K, L, eLM_ToKeeper); 720 call_on_state_create(U, K, L, LookupMode::ToKeeper);
721 721
722 // to see VM name in Decoda debugger 722 // to see VM name in Decoda debugger
723 lua_pushfstring(K, "Keeper #%d", i + 1); // "Keeper #n" 723 lua_pushfstring(K, "Keeper #%d", i + 1); // "Keeper #n"
@@ -785,7 +785,7 @@ void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode
785 int const n{ lua_gettop(L) }; 785 int const n{ lua_gettop(L) };
786 for (int i = val_i_; i <= n; ++i) 786 for (int i = val_i_; i <= n; ++i)
787 { 787 {
788 if (mode_ == eLM_ToKeeper) 788 if (mode_ == LookupMode::ToKeeper)
789 { 789 {
790 if (lua_isnil(L, i)) 790 if (lua_isnil(L, i))
791 { 791 {
@@ -827,7 +827,7 @@ int keeper_call(Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, voi
827 827
828 lua_pushlightuserdata(K, linda); 828 lua_pushlightuserdata(K, linda);
829 829
830 if ((args == 0) || luaG_inter_copy(U, L, K, args, eLM_ToKeeper) == 0) // L->K 830 if ((args == 0) || luaG_inter_copy(U, L, K, args, LookupMode::ToKeeper) == 0) // L->K
831 { 831 {
832 lua_call(K, 1 + args, LUA_MULTRET); 832 lua_call(K, 1 + args, LUA_MULTRET);
833 833
@@ -836,7 +836,7 @@ int keeper_call(Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, voi
836 // this may interrupt a lane, causing the destruction of the underlying OS thread 836 // this may interrupt a lane, causing the destruction of the underlying OS thread
837 // after this, another lane making use of this keeper can get an error code from the mutex-locking function 837 // after this, another lane making use of this keeper can get an error code from the mutex-locking function
838 // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) 838 // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread)
839 if ((retvals > 0) && luaG_inter_move(U, K, L, retvals, eLM_FromKeeper) != 0) // K->L 839 if ((retvals > 0) && luaG_inter_move(U, K, L, retvals, LookupMode::FromKeeper) != 0) // K->L
840 { 840 {
841 retvals = -1; 841 retvals = -1;
842 } 842 }
diff --git a/src/keeper.h b/src/keeper.h
index fc0aa6b..e081bea 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -12,8 +12,8 @@ extern "C" {
12#include "uniquekey.h" 12#include "uniquekey.h"
13 13
14// forwards 14// forwards
15enum class LookupMode;
15struct Universe; 16struct Universe;
16enum LookupMode;
17 17
18struct Keeper 18struct Keeper
19{ 19{
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 8a76217..8890b06 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -464,7 +464,7 @@ static int universe_gc( lua_State* L)
464 while (lane != SELFDESTRUCT_END) 464 while (lane != SELFDESTRUCT_END)
465 { 465 {
466 // attempt a regular unforced hard cancel with a small timeout 466 // attempt a regular unforced hard cancel with a small timeout
467 bool const cancelled = THREAD_ISNULL(lane->thread) || thread_cancel(L, lane, CO_Hard, 0.0001, false, 0.0) != CancelResult::Timeout; 467 bool const cancelled{ THREAD_ISNULL(lane->thread) || thread_cancel(L, lane, CancelOp::Hard, 0.0001, false, 0.0) != CancelResult::Timeout };
468 // if we failed, and we know the thread is waiting on a linda 468 // if we failed, and we know the thread is waiting on a linda
469 if (cancelled == false && lane->status == WAITING && lane->waiting_on != nullptr) 469 if (cancelled == false && lane->status == WAITING && lane->waiting_on != nullptr)
470 { 470 {
@@ -1085,7 +1085,7 @@ LUAG_FUNC(lane_new)
1085 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1085 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1086 1086
1087 // populate with selected libraries at the same time 1087 // populate with selected libraries at the same time
1088 lua_State* const L2{ luaG_newstate(U, L, libs_str) }; // L // L2 1088 lua_State* const L2{ luaG_newstate(U, L, libs_str) }; // L // L2
1089 1089
1090 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1090 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1091 Lane* const lane{ new (U) Lane{ U, L2 } }; 1091 Lane* const lane{ new (U) Lane{ U, L2 } };
@@ -1122,23 +1122,23 @@ LUAG_FUNC(lane_new)
1122 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); 1122 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END));
1123 THREAD_CREATE(&lane->thread, lane_main, lane, priority); 1123 THREAD_CREATE(&lane->thread, lane_main, lane, priority);
1124 1124
1125 STACK_GROW( L2, nargs + 3); // 1125 STACK_GROW( L2, nargs + 3); //
1126 STACK_CHECK_START_REL(L2, 0); 1126 STACK_CHECK_START_REL(L2, 0);
1127 1127
1128 STACK_GROW(L, 3); // func libs priority globals package required gc_cb [... args ...] 1128 STACK_GROW(L, 3); // func libs priority globals package required gc_cb [... args ...]
1129 STACK_CHECK_START_REL(L, 0); 1129 STACK_CHECK_START_REL(L, 0);
1130 1130
1131 // give a default "Lua" name to the thread to see VM name in Decoda debugger 1131 // give a default "Lua" name to the thread to see VM name in Decoda debugger
1132 lua_pushfstring( L2, "Lane #%p", L2); // "..." 1132 lua_pushfstring( L2, "Lane #%p", L2); // "..."
1133 lua_setglobal( L2, "decoda_name"); // 1133 lua_setglobal( L2, "decoda_name"); //
1134 ASSERT_L( lua_gettop( L2) == 0); 1134 ASSERT_L( lua_gettop( L2) == 0);
1135 1135
1136 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END)); 1136 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END));
1137 // package 1137 // package
1138 if (package_idx != 0) 1138 if (package_idx != 0)
1139 { 1139 {
1140 // when copying with mode eLM_LaneBody, should raise an error in case of problem, not leave it one the stack 1140 // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack
1141 (void) luaG_inter_copy_package( U, L, L2, package_idx, eLM_LaneBody); 1141 (void) luaG_inter_copy_package(U, L, L2, package_idx, LookupMode::LaneBody);
1142 } 1142 }
1143 1143
1144 // modules to require in the target lane *before* the function is transfered! 1144 // modules to require in the target lane *before* the function is transfered!
@@ -1154,8 +1154,8 @@ LUAG_FUNC(lane_new)
1154 return luaL_error(L, "expected required module list as a table, got %s", luaL_typename(L, required_idx)); 1154 return luaL_error(L, "expected required module list as a table, got %s", luaL_typename(L, required_idx));
1155 } 1155 }
1156 1156
1157 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil 1157 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil
1158 while( lua_next(L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" 1158 while( lua_next(L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname"
1159 { 1159 {
1160 if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired) 1160 if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired)
1161 { 1161 {
@@ -1169,33 +1169,33 @@ LUAG_FUNC(lane_new)
1169 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); 1169 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name));
1170 1170
1171 // require the module in the target lane 1171 // require the module in the target lane
1172 lua_getglobal( L2, "require"); // require()? 1172 lua_getglobal( L2, "require"); // require()?
1173 if (lua_isnil( L2, -1)) 1173 if (lua_isnil( L2, -1))
1174 { 1174 {
1175 lua_pop( L2, 1); // 1175 lua_pop( L2, 1); //
1176 return luaL_error(L, "cannot pre-require modules without loading 'package' library first"); 1176 return luaL_error(L, "cannot pre-require modules without loading 'package' library first");
1177 } 1177 }
1178 else 1178 else
1179 { 1179 {
1180 lua_pushlstring( L2, name, len); // require() name 1180 lua_pushlstring( L2, name, len); // require() name
1181 if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode 1181 if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode
1182 { 1182 {
1183 // propagate error to main state if any 1183 // propagate error to main state if any
1184 luaG_inter_move(U, L2, L, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error 1184 luaG_inter_move(U, L2, L, 1, LookupMode::LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error
1185 raise_lua_error(L); 1185 raise_lua_error(L);
1186 } 1186 }
1187 // after requiring the module, register the functions it exported in our name<->function database 1187 // after requiring the module, register the functions it exported in our name<->function database
1188 populate_func_lookup_table( L2, -1, name); 1188 populate_func_lookup_table( L2, -1, name);
1189 lua_pop( L2, 1); // 1189 lua_pop( L2, 1); //
1190 } 1190 }
1191 } 1191 }
1192 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] n 1192 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] n
1193 ++ nbRequired; 1193 ++ nbRequired;
1194 } // func libs priority globals package required gc_cb [... args ...] 1194 } // func libs priority globals package required gc_cb [... args ...]
1195 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1195 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1196 } 1196 }
1197 STACK_CHECK(L, 0); 1197 STACK_CHECK(L, 0);
1198 STACK_CHECK(L2, 0); // 1198 STACK_CHECK(L2, 0); //
1199 1199
1200 // Appending the specified globals to the global environment 1200 // Appending the specified globals to the global environment
1201 // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed... 1201 // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed...
@@ -1209,17 +1209,17 @@ LUAG_FUNC(lane_new)
1209 } 1209 }
1210 1210
1211 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1211 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1212 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil 1212 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil
1213 // Lua 5.2 wants us to push the globals table on the stack 1213 // Lua 5.2 wants us to push the globals table on the stack
1214 lua_pushglobaltable(L2); // _G 1214 lua_pushglobaltable(L2); // _G
1215 while( lua_next(L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v 1215 while( lua_next(L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v
1216 { 1216 {
1217 luaG_inter_copy(U, L, L2, 2, eLM_LaneBody); // _G k v 1217 luaG_inter_copy(U, L, L2, 2, LookupMode::LaneBody); // _G k v
1218 // assign it in L2's globals table 1218 // assign it in L2's globals table
1219 lua_rawset(L2, -3); // _G 1219 lua_rawset(L2, -3); // _G
1220 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] k 1220 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] k
1221 } // func libs priority globals package required gc_cb [... args ...] 1221 } // func libs priority globals package required gc_cb [... args ...]
1222 lua_pop( L2, 1); // 1222 lua_pop( L2, 1); //
1223 1223
1224 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1224 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1225 } 1225 }
@@ -1232,8 +1232,8 @@ LUAG_FUNC(lane_new)
1232 int res; 1232 int res;
1233 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); 1233 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END));
1234 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1234 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1235 lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func 1235 lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func
1236 res = luaG_inter_move(U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func 1236 res = luaG_inter_move(U, L, L2, 1, LookupMode::LaneBody); // func libs priority globals package required gc_cb [... args ...] // func
1237 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1237 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1238 if (res != 0) 1238 if (res != 0)
1239 { 1239 {
@@ -1243,7 +1243,7 @@ LUAG_FUNC(lane_new)
1243 else if (lua_type(L, 1) == LUA_TSTRING) 1243 else if (lua_type(L, 1) == LUA_TSTRING)
1244 { 1244 {
1245 // compile the string 1245 // compile the string
1246 if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func 1246 if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func
1247 { 1247 {
1248 return luaL_error(L, "error when parsing lane function code"); 1248 return luaL_error(L, "error when parsing lane function code");
1249 } 1249 }
@@ -1258,7 +1258,7 @@ LUAG_FUNC(lane_new)
1258 int res; 1258 int res;
1259 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); 1259 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END));
1260 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1260 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1261 res = luaG_inter_move(U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] 1261 res = luaG_inter_move(U, L, L2, nargs, LookupMode::LaneBody); // func libs priority globals package required gc_cb // func [... args ...]
1262 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1262 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1263 if (res != 0) 1263 if (res != 0)
1264 { 1264 {
@@ -1271,31 +1271,31 @@ LUAG_FUNC(lane_new)
1271 STACK_CHECK( L2, 1 + nargs); 1271 STACK_CHECK( L2, 1 + nargs);
1272 1272
1273 // a Lane full userdata needs a single uservalue 1273 // a Lane full userdata needs a single uservalue
1274 Lane** const ud{ lua_newuserdatauv<Lane*>(L, 1) }; // func libs priority globals package required gc_cb lane 1274 Lane** const ud{ lua_newuserdatauv<Lane*>(L, 1) }; // func libs priority globals package required gc_cb lane
1275 *ud = lane; // don't forget to store the pointer in the userdata! 1275 *ud = lane; // don't forget to store the pointer in the userdata!
1276 1276
1277 // Set metatable for the userdata 1277 // Set metatable for the userdata
1278 // 1278 //
1279 lua_pushvalue(L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt 1279 lua_pushvalue(L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt
1280 lua_setmetatable(L, -2); // func libs priority globals package required gc_cb lane 1280 lua_setmetatable(L, -2); // func libs priority globals package required gc_cb lane
1281 STACK_CHECK(L, 1); 1281 STACK_CHECK(L, 1);
1282 1282
1283 // Create uservalue for the userdata 1283 // Create uservalue for the userdata
1284 // (this is where lane body return values will be stored when the handle is indexed by a numeric key) 1284 // (this is where lane body return values will be stored when the handle is indexed by a numeric key)
1285 lua_newtable(L); // func libs cancelstep priority globals package required gc_cb lane uv 1285 lua_newtable(L); // func libs cancelstep priority globals package required gc_cb lane uv
1286 1286
1287 // Store the gc_cb callback in the uservalue 1287 // Store the gc_cb callback in the uservalue
1288 if (gc_cb_idx > 0) 1288 if (gc_cb_idx > 0)
1289 { 1289 {
1290 GCCB_KEY.pushKey(L); // func libs priority globals package required gc_cb lane uv k 1290 GCCB_KEY.pushKey(L); // func libs priority globals package required gc_cb lane uv k
1291 lua_pushvalue(L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb 1291 lua_pushvalue(L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb
1292 lua_rawset(L, -3); // func libs priority globals package required gc_cb lane uv 1292 lua_rawset(L, -3); // func libs priority globals package required gc_cb lane uv
1293 } 1293 }
1294 1294
1295 lua_setiuservalue(L, -2, 1); // func libs priority globals package required gc_cb lane 1295 lua_setiuservalue(L, -2, 1); // func libs priority globals package required gc_cb lane
1296 1296
1297 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). 1297 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
1298 LANE_POINTER_REGKEY.setValue(L2, [lane](lua_State* L) { lua_pushlightuserdata(L, lane); }); // func [... args ...] 1298 LANE_POINTER_REGKEY.setValue(L2, [lane](lua_State* L) { lua_pushlightuserdata(L, lane); }); // func [... args ...]
1299 1299
1300 STACK_CHECK(L, 1); 1300 STACK_CHECK(L, 1);
1301 STACK_CHECK(L2, 1 + nargs); 1301 STACK_CHECK(L2, 1 + nargs);
@@ -1482,7 +1482,7 @@ LUAG_FUNC(thread_join)
1482 case DONE: 1482 case DONE:
1483 { 1483 {
1484 int const n{ lua_gettop(L2) }; // whole L2 stack 1484 int const n{ lua_gettop(L2) }; // whole L2 stack
1485 if ((n > 0) && (luaG_inter_move(U, L2, L, n, eLM_LaneBody) != 0)) 1485 if ((n > 0) && (luaG_inter_move(U, L2, L, n, LookupMode::LaneBody) != 0))
1486 { 1486 {
1487 return luaL_error(L, "tried to copy unsupported types"); 1487 return luaL_error(L, "tried to copy unsupported types");
1488 } 1488 }
@@ -1496,7 +1496,7 @@ LUAG_FUNC(thread_join)
1496 STACK_GROW(L, 3); 1496 STACK_GROW(L, 3);
1497 lua_pushnil(L); 1497 lua_pushnil(L);
1498 // 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 ... 1498 // 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 ...
1499 if (luaG_inter_move(U, L2, L, n, eLM_LaneBody) != 0) // nil "err" [trace] 1499 if (luaG_inter_move(U, L2, L, n, LookupMode::LaneBody) != 0) // nil "err" [trace]
1500 { 1500 {
1501 return luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n)); 1501 return luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n));
1502 } 1502 }
@@ -1967,7 +1967,7 @@ LUAG_FUNC(configure)
1967 STACK_CHECK(L, 2); 1967 STACK_CHECK(L, 2);
1968 1968
1969 { 1969 {
1970 char const* errmsg{ push_deep_proxy(L, U->timer_deep, 0, eLM_LaneBody) }; // settings M timer_deep 1970 char const* errmsg{ push_deep_proxy(L, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep
1971 if (errmsg != nullptr) 1971 if (errmsg != nullptr)
1972 { 1972 {
1973 return luaL_error(L, errmsg); 1973 return luaL_error(L, errmsg);
diff --git a/src/linda.cpp b/src/linda.cpp
index 14eba2d..37a74b0 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -256,7 +256,7 @@ LUAG_FUNC(linda_send)
256 } 256 }
257 257
258 // convert nils to some special non-nil sentinel in sent values 258 // convert nils to some special non-nil sentinel in sent values
259 keeper_toggle_nil_sentinels(L, key_i + 1, eLM_ToKeeper); 259 keeper_toggle_nil_sentinels(L, key_i + 1, LookupMode::ToKeeper);
260 bool ret{ false }; 260 bool ret{ false };
261 CancelRequest cancel{ CancelRequest::None }; 261 CancelRequest cancel{ CancelRequest::None };
262 int pushed{ 0 }; 262 int pushed{ 0 };
@@ -448,7 +448,7 @@ LUAG_FUNC(linda_receive)
448 { 448 {
449 ASSERT_L(pushed >= expected_pushed_min && pushed <= expected_pushed_max); 449 ASSERT_L(pushed >= expected_pushed_min && pushed <= expected_pushed_max);
450 // replace sentinels with real nils 450 // replace sentinels with real nils
451 keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed, eLM_FromKeeper); 451 keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed, LookupMode::FromKeeper);
452 // To be done from within the 'K' locking area 452 // To be done from within the 'K' locking area
453 // 453 //
454 SIGNAL_ALL(&linda->read_happened); 454 SIGNAL_ALL(&linda->read_happened);
@@ -527,7 +527,7 @@ LUAG_FUNC(linda_set)
527 if (has_value) 527 if (has_value)
528 { 528 {
529 // convert nils to some special non-nil sentinel in sent values 529 // convert nils to some special non-nil sentinel in sent values
530 keeper_toggle_nil_sentinels(L, 3, eLM_ToKeeper); 530 keeper_toggle_nil_sentinels(L, 3, LookupMode::ToKeeper);
531 } 531 }
532 pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L, linda, 2); 532 pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L, linda, 2);
533 if (pushed >= 0) // no error? 533 if (pushed >= 0) // no error?
@@ -603,7 +603,7 @@ LUAG_FUNC(linda_get)
603 pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L, linda, 2); 603 pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L, linda, 2);
604 if (pushed > 0) 604 if (pushed > 0)
605 { 605 {
606 keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed, eLM_FromKeeper); 606 keeper_toggle_nil_sentinels(L, lua_gettop(L) - pushed, LookupMode::FromKeeper);
607 } 607 }
608 } 608 }
609 else // linda is cancelled 609 else // linda is cancelled
@@ -843,7 +843,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
843{ 843{
844 switch( op_) 844 switch( op_)
845 { 845 {
846 case eDO_new: 846 case DeepOp::New:
847 { 847 {
848 size_t name_len = 0; 848 size_t name_len = 0;
849 char const* linda_name = nullptr; 849 char const* linda_name = nullptr;
@@ -881,7 +881,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
881 return linda; 881 return linda;
882 } 882 }
883 883
884 case eDO_delete: 884 case DeepOp::Delete:
885 { 885 {
886 Linda* const linda{ lua_tolightuserdata<Linda>(L, 1) }; 886 Linda* const linda{ lua_tolightuserdata<Linda>(L, 1) };
887 ASSERT_L(linda); 887 ASSERT_L(linda);
@@ -899,7 +899,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
899 return nullptr; 899 return nullptr;
900 } 900 }
901 901
902 case eDO_metatable: 902 case DeepOp::Metatable:
903 { 903 {
904 STACK_CHECK_START_REL(L, 0); 904 STACK_CHECK_START_REL(L, 0);
905 lua_newtable(L); 905 lua_newtable(L);
@@ -970,7 +970,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
970 return nullptr; 970 return nullptr;
971 } 971 }
972 972
973 case eDO_module: 973 case DeepOp::Module:
974 // linda is a special case because we know lanes must be loaded from the main lua state 974 // linda is a special case because we know lanes must be loaded from the main lua state
975 // to be able to ever get here, so we know it will remain loaded as long a the main state is around 975 // to be able to ever get here, so we know it will remain loaded as long a the main state is around
976 // in other words, forever. 976 // in other words, forever.
diff --git a/src/state.cpp b/src/state.cpp
index 2678280..55540c8 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -205,7 +205,7 @@ static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2)
205 205
206 CONFIG_REGKEY.pushValue(L); // config 206 CONFIG_REGKEY.pushValue(L); // config
207 // copy settings from from source to destination registry 207 // copy settings from from source to destination registry
208 if( luaG_inter_move( U, L, L2, 1, eLM_LaneBody) < 0) // // config 208 if( luaG_inter_move( U, L, L2, 1, LookupMode::LaneBody) < 0) // // config
209 { 209 {
210 (void) luaL_error( L, "failed to copy settings when loading lanes.core"); 210 (void) luaL_error( L, "failed to copy settings when loading lanes.core");
211 } 211 }
@@ -291,7 +291,7 @@ void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMod
291 } 291 }
292 else // Lua function located in the config table, copied when we opened "lanes.core" 292 else // Lua function located in the config table, copied when we opened "lanes.core"
293 { 293 {
294 if (mode_ != eLM_LaneBody) 294 if (mode_ != LookupMode::LaneBody)
295 { 295 {
296 // if attempting to call in a keeper state, do nothing because the function doesn't exist there 296 // if attempting to call in a keeper state, do nothing because the function doesn't exist there
297 // this doesn't count as an error though 297 // this doesn't count as an error though
@@ -413,7 +413,7 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
413 413
414 // call this after the base libraries are loaded and GC is restarted 414 // call this after the base libraries are loaded and GC is restarted
415 // will raise an error in from_ in case of problem 415 // will raise an error in from_ in case of problem
416 call_on_state_create( U, L, from_, eLM_LaneBody); 416 call_on_state_create(U, L, from_, LookupMode::LaneBody);
417 417
418 STACK_CHECK(L, 0); 418 STACK_CHECK(L, 0);
419 // after all this, register everything we find in our name<->function database 419 // after all this, register everything we find in our name<->function database
diff --git a/src/state.h b/src/state.h
index 0ffab02..0e35e89 100644
--- a/src/state.h
+++ b/src/state.h
@@ -1,18 +1,18 @@
1#pragma once 1#pragma once
2 2
3#include "threading.h"
4#include "deep.h"
5
6#include "macros_and_utils.h" 3#include "macros_and_utils.h"
7 4
8void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State *L); 5// forwards
6struct Universe;
7
8void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L);
9 9
10// ################################################################################################ 10// ################################################################################################
11 11
12lua_State* create_state( Universe* U, lua_State* from_); 12lua_State* create_state(Universe* U, lua_State* from_);
13lua_State* luaG_newstate( Universe* U, lua_State* _from, char const* libs); 13lua_State* luaG_newstate(Universe* U, lua_State* _from, char const* libs);
14 14
15// ################################################################################################ 15// ################################################################################################
16 16
17void initialize_on_state_create( Universe* U, lua_State* L); 17void initialize_on_state_create(Universe* U, lua_State* L);
18void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMode mode_); 18void 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 98224ae..103122e 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -301,7 +301,9 @@ FuncSubType luaG_getfuncsubtype( lua_State *L, int _i)
301 return FST_FastJIT; 301 return FST_FastJIT;
302} 302}
303 303
304static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out) 304// #################################################################################################
305
306static lua_CFunction luaG_tocfunction(lua_State* L, int _i, FuncSubType* _out)
305{ 307{
306 lua_CFunction p = lua_tocfunction( L, _i); 308 lua_CFunction p = lua_tocfunction( L, _i);
307 *_out = luaG_getfuncsubtype( L, _i); 309 *_out = luaG_getfuncsubtype( L, _i);
@@ -311,6 +313,8 @@ static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out)
311// crc64/we of string "LOOKUPCACHE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 313// crc64/we of string "LOOKUPCACHE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
312static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull }; 314static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull };
313 315
316// #################################################################################################
317
314// inspired from tconcat() in ltablib.c 318// inspired from tconcat() in ltablib.c
315static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) 319static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
316{ 320{
@@ -336,6 +340,8 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
336 return lua_tolstring( L, -1, length); 340 return lua_tolstring( L, -1, length);
337} 341}
338 342
343// #################################################################################################
344
339/* 345/*
340 * receives 2 arguments: a name k and an object o 346 * receives 2 arguments: a name k and an object o
341 * add two entries ["fully.qualified.name"] = o 347 * add two entries ["fully.qualified.name"] = o
@@ -418,7 +424,9 @@ static void update_lookup_entry( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State*
418 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 424 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
419} 425}
420 426
421static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) 427// #################################################################################################
428
429static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _i, int _depth)
422{ 430{
423 lua_Integer visit_count; 431 lua_Integer visit_count;
424 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i 432 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i
@@ -541,6 +549,8 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U
541 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 549 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
542} 550}
543 551
552// #################################################################################################
553
544/* 554/*
545 * create a "fully.qualified.name" <-> function equivalence database 555 * create a "fully.qualified.name" <-> function equivalence database
546 */ 556 */
@@ -605,6 +615,8 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
605 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 615 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
606} 616}
607 617
618// #################################################################################################
619
608/*---=== Inter-state copying ===---*/ 620/*---=== Inter-state copying ===---*/
609 621
610// crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/ 622// crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/
@@ -651,12 +663,15 @@ static lua_Integer get_mt_id( Universe* U, lua_State* L, int i)
651 return id; 663 return id;
652} 664}
653 665
666// #################################################################################################
667
654// function sentinel used to transfer native functions from/to keeper states 668// function sentinel used to transfer native functions from/to keeper states
655static int func_lookup_sentinel( lua_State* L) 669static int func_lookup_sentinel( lua_State* L)
656{ 670{
657 return luaL_error( L, "function lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); 671 return luaL_error( L, "function lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1)));
658} 672}
659 673
674// #################################################################################################
660 675
661// function sentinel used to transfer native table from/to keeper states 676// function sentinel used to transfer native table from/to keeper states
662static int table_lookup_sentinel( lua_State* L) 677static int table_lookup_sentinel( lua_State* L)
@@ -664,12 +679,16 @@ static int table_lookup_sentinel( lua_State* L)
664 return luaL_error( L, "table lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); 679 return luaL_error( L, "table lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1)));
665} 680}
666 681
682// #################################################################################################
683
667// function sentinel used to transfer cloned full userdata from/to keeper states 684// function sentinel used to transfer cloned full userdata from/to keeper states
668static int userdata_clone_sentinel( lua_State* L) 685static int userdata_clone_sentinel( lua_State* L)
669{ 686{
670 return luaL_error( L, "userdata clone sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); 687 return luaL_error( L, "userdata clone sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1)));
671} 688}
672 689
690// #################################################################################################
691
673/* 692/*
674 * retrieve the name of a function/table in the lookup database 693 * retrieve the name of a function/table in the lookup database
675 */ 694 */
@@ -680,7 +699,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char
680 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... 699 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ...
681 STACK_CHECK_START_REL(L, 0); 700 STACK_CHECK_START_REL(L, 0);
682 STACK_GROW( L, 3); // up to 3 slots are necessary on error 701 STACK_GROW( L, 3); // up to 3 slots are necessary on error
683 if( mode_ == eLM_FromKeeper) 702 if (mode_ == LookupMode::FromKeeper)
684 { 703 {
685 lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! 704 lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel!
686 if( f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) 705 if( f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel)
@@ -707,7 +726,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char
707 fqn = lua_tolstring( L, -1, len_); 726 fqn = lua_tolstring( L, -1, len_);
708 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); 727 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn));
709 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database 728 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
710 lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... v ... 729 lua_pop( L, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ...
711 STACK_CHECK( L, 0); 730 STACK_CHECK( L, 0);
712 if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) 731 if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables)
713 { 732 {
@@ -741,6 +760,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char
741 return fqn; 760 return fqn;
742} 761}
743 762
763// #################################################################################################
744 764
745/* 765/*
746 * Push a looked-up table, or nothing if we found nothing 766 * Push a looked-up table, or nothing if we found nothing
@@ -763,14 +783,14 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
763 (void) luaL_error( L, "internal error: unknown lookup mode"); 783 (void) luaL_error( L, "internal error: unknown lookup mode");
764 return false; 784 return false;
765 785
766 case eLM_ToKeeper: 786 case LookupMode::ToKeeper:
767 // push a sentinel closure that holds the lookup name as upvalue 787 // push a sentinel closure that holds the lookup name as upvalue
768 lua_pushlstring( L2, fqn, len); // "f.q.n" 788 lua_pushlstring( L2, fqn, len); // "f.q.n"
769 lua_pushcclosure( L2, table_lookup_sentinel, 1); // f 789 lua_pushcclosure( L2, table_lookup_sentinel, 1); // f
770 break; 790 break;
771 791
772 case eLM_LaneBody: 792 case LookupMode::LaneBody:
773 case eLM_FromKeeper: 793 case LookupMode::FromKeeper:
774 LOOKUP_REGKEY.pushValue(L2); // {} 794 LOOKUP_REGKEY.pushValue(L2); // {}
775 STACK_CHECK( L2, 1); 795 STACK_CHECK( L2, 1);
776 ASSERT_L( lua_istable( L2, -1)); 796 ASSERT_L( lua_istable( L2, -1));
@@ -778,7 +798,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
778 lua_rawget( L2, -2); // {} t 798 lua_rawget( L2, -2); // {} t
779 // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) 799 // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead)
780 // but not when we extract something out of a keeper, as there is nothing to clone! 800 // but not when we extract something out of a keeper, as there is nothing to clone!
781 if( lua_isnil( L2, -1) && mode_ == eLM_LaneBody) 801 if (lua_isnil(L2, -1) && mode_ == LookupMode::LaneBody)
782 { 802 {
783 lua_pop( L2, 2); // 803 lua_pop( L2, 2); //
784 STACK_CHECK( L2, 0); 804 STACK_CHECK( L2, 0);
@@ -793,9 +813,9 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
793 lua_getglobal( L2, "decoda_name"); // {} t decoda_name 813 lua_getglobal( L2, "decoda_name"); // {} t decoda_name
794 to = lua_tostring( L2, -1); 814 to = lua_tostring( L2, -1);
795 lua_pop( L2, 1); // {} t 815 lua_pop( L2, 1); // {} t
796 // when mode_ == eLM_FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error 816 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
797 (void) luaL_error( 817 (void) luaL_error(
798 (mode_ == eLM_FromKeeper) ? L2 : L 818 (mode_ == LookupMode::FromKeeper) ? L2 : L
799 , "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database." 819 , "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database."
800 , from ? from : "main" 820 , from ? from : "main"
801 , fqn 821 , fqn
@@ -810,6 +830,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
810 return true; 830 return true;
811} 831}
812 832
833// #################################################################################################
813 834
814/* 835/*
815 * Check if we've already copied the same table from 'L', and 836 * Check if we've already copied the same table from 'L', and
@@ -852,6 +873,7 @@ static bool push_cached_table(lua_State* L2, int L2_cache_i, lua_State* L, int i
852 return !not_found_in_cache; 873 return !not_found_in_cache;
853} 874}
854 875
876// #################################################################################################
855 877
856/* 878/*
857 * Return some name helping to identify an object 879 * Return some name helping to identify an object
@@ -998,6 +1020,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
998 return shortest_; 1020 return shortest_;
999} 1021}
1000 1022
1023// #################################################################################################
1001 1024
1002/* 1025/*
1003 * "type", "name" = lanes.nameof( o) 1026 * "type", "name" = lanes.nameof( o)
@@ -1046,6 +1069,7 @@ int luaG_nameof( lua_State* L)
1046 return 2; 1069 return 2;
1047} 1070}
1048 1071
1072// #################################################################################################
1049 1073
1050/* 1074/*
1051 * Push a looked-up native/LuaJIT function. 1075 * Push a looked-up native/LuaJIT function.
@@ -1064,14 +1088,14 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo
1064 (void) luaL_error( L, "internal error: unknown lookup mode"); 1088 (void) luaL_error( L, "internal error: unknown lookup mode");
1065 return; 1089 return;
1066 1090
1067 case eLM_ToKeeper: 1091 case LookupMode::ToKeeper:
1068 // push a sentinel closure that holds the lookup name as upvalue 1092 // push a sentinel closure that holds the lookup name as upvalue
1069 lua_pushlstring( L2, fqn, len); // "f.q.n" 1093 lua_pushlstring( L2, fqn, len); // "f.q.n"
1070 lua_pushcclosure( L2, func_lookup_sentinel, 1); // f 1094 lua_pushcclosure( L2, func_lookup_sentinel, 1); // f
1071 break; 1095 break;
1072 1096
1073 case eLM_LaneBody: 1097 case LookupMode::LaneBody:
1074 case eLM_FromKeeper: 1098 case LookupMode::FromKeeper:
1075 LOOKUP_REGKEY.pushValue(L2); // {} 1099 LOOKUP_REGKEY.pushValue(L2); // {}
1076 STACK_CHECK( L2, 1); 1100 STACK_CHECK( L2, 1);
1077 ASSERT_L( lua_istable( L2, -1)); 1101 ASSERT_L( lua_istable( L2, -1));
@@ -1088,9 +1112,9 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo
1088 lua_getglobal( L2, "decoda_name"); // {} f decoda_name 1112 lua_getglobal( L2, "decoda_name"); // {} f decoda_name
1089 to = lua_tostring( L2, -1); 1113 to = lua_tostring( L2, -1);
1090 lua_pop( L2, 1); // {} f 1114 lua_pop( L2, 1); // {} f
1091 // when mode_ == eLM_FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error 1115 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
1092 (void) luaL_error( 1116 (void) luaL_error(
1093 (mode_ == eLM_FromKeeper) ? L2 : L 1117 (mode_ == LookupMode::FromKeeper) ? L2 : L
1094 , "%s%s: function '%s' not found in %s destination transfer database." 1118 , "%s%s: function '%s' not found in %s destination transfer database."
1095 , lua_isnil( L2, -1) ? "" : "INTERNAL ERROR IN " 1119 , lua_isnil( L2, -1) ? "" : "INTERNAL ERROR IN "
1096 , from ? from : "main" 1120 , from ? from : "main"
@@ -1103,7 +1127,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo
1103 break; 1127 break;
1104 1128
1105 /* keep it in case I need it someday, who knows... 1129 /* keep it in case I need it someday, who knows...
1106 case eLM_RawFunctions: 1130 case LookupMode::RawFunctions:
1107 { 1131 {
1108 int n; 1132 int n;
1109 char const* upname; 1133 char const* upname;
@@ -1121,6 +1145,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo
1121 STACK_CHECK( L2, 1); 1145 STACK_CHECK( L2, 1);
1122} 1146}
1123 1147
1148// #################################################################################################
1124 1149
1125/* 1150/*
1126 * Copy a function over, which has not been found in the cache. 1151 * Copy a function over, which has not been found in the cache.
@@ -1144,12 +1169,14 @@ static char const* lua_type_names[] =
1144}; 1169};
1145static char const* vt_names[] = 1170static char const* vt_names[] =
1146{ 1171{
1147 "VT_NORMAL" 1172 "VT::NORMAL"
1148 , "VT_KEY" 1173 , "VT::KEY"
1149 , "VT_METATABLE" 1174 , "VT::METATABLE"
1150}; 1175};
1151#endif // USE_DEBUG_SPEW() 1176#endif // USE_DEBUG_SPEW()
1152 1177
1178// #################################################################################################
1179
1153// Lua 5.4.3 style of dumping (see lstrlib.c) 1180// Lua 5.4.3 style of dumping (see lstrlib.c)
1154// we have to do it that way because we can't unbalance the stack between buffer operations 1181// we have to do it that way because we can't unbalance the stack between buffer operations
1155// namely, this means we can't push a function on top of the stack *after* we initialize the buffer! 1182// namely, this means we can't push a function on top of the stack *after* we initialize the buffer!
@@ -1165,6 +1192,8 @@ static int buf_writer( lua_State* L, void const* b, size_t size, void* ud)
1165 return 0; 1192 return 0;
1166} 1193}
1167 1194
1195// #################################################################################################
1196
1168static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 1197static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_)
1169{ 1198{
1170 int n, needToPush; 1199 int n, needToPush;
@@ -1277,7 +1306,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1277#endif // LUA_VERSION_NUM 1306#endif // LUA_VERSION_NUM
1278 { 1307 {
1279 DEBUGSPEW_CODE( fprintf( stderr, "copying value\n")); 1308 DEBUGSPEW_CODE( fprintf( stderr, "copying value\n"));
1280 if( !inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL, mode_, upname)) // ... {cache} ... function <upvalues> 1309 if( !inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT::NORMAL, mode_, upname)) // ... {cache} ... function <upvalues>
1281 { 1310 {
1282 luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); 1311 luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1));
1283 } 1312 }
@@ -1311,6 +1340,8 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1311 STACK_CHECK( L, 0); 1340 STACK_CHECK( L, 0);
1312} 1341}
1313 1342
1343// #################################################################################################
1344
1314/* 1345/*
1315 * Check if we've already copied the same function from 'L', and reuse the old 1346 * Check if we've already copied the same function from 'L', and reuse the old
1316 * copy. 1347 * copy.
@@ -1370,6 +1401,8 @@ static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta
1370 } 1401 }
1371} 1402}
1372 1403
1404// #################################################################################################
1405
1373static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 1406static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_)
1374{ 1407{
1375 STACK_CHECK_START_REL(L, 0); 1408 STACK_CHECK_START_REL(L, 0);
@@ -1389,7 +1422,7 @@ static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lu
1389 if( lua_isnil( L2, -1)) 1422 if( lua_isnil( L2, -1))
1390 { // L2 did not know the metatable 1423 { // L2 did not know the metatable
1391 lua_pop( L2, 1); // _R[REG_MTID] 1424 lua_pop( L2, 1); // _R[REG_MTID]
1392 if( inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_METATABLE, mode_, upName_)) // _R[REG_MTID] mt 1425 if (inter_copy_one(U, L2, L2_cache_i, L, lua_gettop( L), VT::METATABLE, mode_, upName_)) // _R[REG_MTID] mt
1393 { 1426 {
1394 STACK_CHECK( L2, 2); 1427 STACK_CHECK( L2, 2);
1395 // mt_id -> metatable 1428 // mt_id -> metatable
@@ -1419,13 +1452,15 @@ static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lu
1419 return false; 1452 return false;
1420} 1453}
1421 1454
1422static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, enum e_vt vt, LookupMode mode_, char const* upName_) 1455// #################################################################################################
1456
1457static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, VT vt_, LookupMode mode_, char const* upName_)
1423{ 1458{
1424 int val_i = lua_gettop(L); 1459 int val_i = lua_gettop(L);
1425 int key_i = val_i - 1; 1460 int key_i = val_i - 1;
1426 1461
1427 // Only basic key types are copied over; others ignored 1462 // Only basic key types are copied over; others ignored
1428 if( inter_copy_one( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_)) 1463 if (inter_copy_one(U, L2, 0 /*key*/, L, key_i, VT::KEY, mode_, upName_))
1429 { 1464 {
1430 char* valPath = (char*) upName_; 1465 char* valPath = (char*) upName_;
1431 if( U->verboseErrors) 1466 if( U->verboseErrors)
@@ -1471,18 +1506,20 @@ static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i,
1471 * Contents of metatables are copied with cache checking; 1506 * Contents of metatables are copied with cache checking;
1472 * important to detect loops. 1507 * important to detect loops.
1473 */ 1508 */
1474 if( inter_copy_one( U, L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath)) 1509 if (inter_copy_one(U, L2, L2_cache_i, L, val_i, VT::NORMAL, mode_, valPath))
1475 { 1510 {
1476 ASSERT_L( lua_istable( L2, -3)); 1511 ASSERT_L( lua_istable( L2, -3));
1477 lua_rawset( L2, -3); // add to table (pops key & val) 1512 lua_rawset( L2, -3); // add to table (pops key & val)
1478 } 1513 }
1479 else 1514 else
1480 { 1515 {
1481 luaL_error( L, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT_NORMAL) ? "table" : "metatable", valPath, luaL_typename( L, val_i)); 1516 luaL_error(L, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt_ == VT::NORMAL) ? "table" : "metatable", valPath, luaL_typename(L, val_i));
1482 } 1517 }
1483 } 1518 }
1484} 1519}
1485 1520
1521// #################################################################################################
1522
1486/* 1523/*
1487* The clone cache is a weak valued table listing all clones, indexed by their userdatapointer 1524* The clone cache is a weak valued table listing all clones, indexed by their userdatapointer
1488* fnv164 of string "CLONABLES_CACHE_KEY" generated at https://www.pelock.com/products/hash-calculator 1525* fnv164 of string "CLONABLES_CACHE_KEY" generated at https://www.pelock.com/products/hash-calculator
@@ -1541,9 +1578,9 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1541 // create the clone userdata with the required number of uservalue slots 1578 // create the clone userdata with the required number of uservalue slots
1542 clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... u 1579 clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... u
1543 // copy the metatable in the target state, and give it to the clone we put there 1580 // copy the metatable in the target state, and give it to the clone we put there
1544 if( inter_copy_one( U, L2, L2_cache_i, L, mt, VT_NORMAL, mode_, upName_)) // ... u mt|sentinel 1581 if (inter_copy_one(U, L2, L2_cache_i, L, mt, VT::NORMAL, mode_, upName_)) // ... u mt|sentinel
1545 { 1582 {
1546 if( eLM_ToKeeper == mode_) // ... u sentinel 1583 if( LookupMode::ToKeeper == mode_) // ... u sentinel
1547 { 1584 {
1548 ASSERT_L( lua_tocfunction( L2, -1) == table_lookup_sentinel); 1585 ASSERT_L( lua_tocfunction( L2, -1) == table_lookup_sentinel);
1549 // we want to create a new closure with a 'clone sentinel' function, where the upvalues are the userdata and the metatable fqn 1586 // we want to create a new closure with a 'clone sentinel' function, where the upvalues are the userdata and the metatable fqn
@@ -1568,21 +1605,21 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1568 lua_pushvalue( L2, -2); // ... u source u 1605 lua_pushvalue( L2, -2); // ... u source u
1569 lua_rawset( L2, L2_cache_i); // ... u 1606 lua_rawset( L2, L2_cache_i); // ... u
1570 // make sure we have the userdata now 1607 // make sure we have the userdata now
1571 if( eLM_ToKeeper == mode_) // ... userdata_clone_sentinel 1608 if( LookupMode::ToKeeper == mode_) // ... userdata_clone_sentinel
1572 { 1609 {
1573 lua_getupvalue( L2, -1, 2); // ... userdata_clone_sentinel u 1610 lua_getupvalue( L2, -1, 2); // ... userdata_clone_sentinel u
1574 } 1611 }
1575 // assign uservalues 1612 // assign uservalues
1576 while( uvi > 0) 1613 while( uvi > 0)
1577 { 1614 {
1578 inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // ... u uv 1615 inter_copy_one(U, L2, L2_cache_i, L, lua_absindex( L, -1), VT::NORMAL, mode_, upName_); // ... u uv
1579 lua_pop( L, 1); // ... mt __lanesclone [uv]* 1616 lua_pop( L, 1); // ... mt __lanesclone [uv]*
1580 // this pops the value from the stack 1617 // this pops the value from the stack
1581 lua_setiuservalue( L2, -2, uvi); // ... u 1618 lua_setiuservalue( L2, -2, uvi); // ... u
1582 -- uvi; 1619 -- uvi;
1583 } 1620 }
1584 // when we are done, all uservalues are popped from the source stack, and we want only the single transferred value in the destination 1621 // when we are done, all uservalues are popped from the source stack, and we want only the single transferred value in the destination
1585 if( eLM_ToKeeper == mode_) // ... userdata_clone_sentinel u 1622 if( LookupMode::ToKeeper == mode_) // ... userdata_clone_sentinel u
1586 { 1623 {
1587 lua_pop( L2, 1); // ... userdata_clone_sentinel 1624 lua_pop( L2, 1); // ... userdata_clone_sentinel
1588 } 1625 }
@@ -1602,11 +1639,13 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1602 return true; 1639 return true;
1603} 1640}
1604 1641
1605static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) 1642// #################################################################################################
1643
1644static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_)
1606{ 1645{
1607 STACK_CHECK_START_REL(L, 0); 1646 STACK_CHECK_START_REL(L, 0);
1608 STACK_CHECK_START_REL(L2, 0); 1647 STACK_CHECK_START_REL(L2, 0);
1609 if( vt == VT_KEY) 1648 if (vt_ == VT::KEY)
1610 { 1649 {
1611 return false; 1650 return false;
1612 } 1651 }
@@ -1650,9 +1689,11 @@ static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_
1650 return true; 1689 return true;
1651} 1690}
1652 1691
1653static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int source_i_, enum e_vt vt, LookupMode mode_, char const* upName_) 1692// #################################################################################################
1693
1694static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int source_i_, VT vt_, LookupMode mode_, char const* upName_)
1654{ 1695{
1655 if( vt == VT_KEY) 1696 if (vt_ == VT::KEY)
1656 { 1697 {
1657 return false; 1698 return false;
1658 } 1699 }
@@ -1709,7 +1750,7 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_
1709 // transfer and assign uservalues 1750 // transfer and assign uservalues
1710 while( uvi > 0) 1751 while( uvi > 0)
1711 { 1752 {
1712 inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), vt, mode_, upName_); // ... mt u uv 1753 inter_copy_one(U, L2, L2_cache_i, L, lua_absindex(L, -1), vt_, mode_, upName_); // ... mt u uv
1713 lua_pop( L, 1); // ... u [uv]* 1754 lua_pop( L, 1); // ... u [uv]*
1714 // this pops the value from the stack 1755 // this pops the value from the stack
1715 lua_setiuservalue( L2, -2, uvi); // ... mt u 1756 lua_setiuservalue( L2, -2, uvi); // ... mt u
@@ -1743,9 +1784,11 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_
1743 return true; 1784 return true;
1744} 1785}
1745 1786
1746static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) 1787// #################################################################################################
1788
1789static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_)
1747{ 1790{
1748 if( vt == VT_KEY) 1791 if (vt_ == VT::KEY)
1749 { 1792 {
1750 return false; 1793 return false;
1751 } 1794 }
@@ -1787,7 +1830,7 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta
1787 while( lua_next( L, i)) 1830 while( lua_next( L, i))
1788 { 1831 {
1789 // need a function to prevent overflowing the stack with verboseErrors-induced alloca() 1832 // need a function to prevent overflowing the stack with verboseErrors-induced alloca()
1790 inter_copy_keyvaluepair( U, L2, L2_cache_i, L, vt, mode_, upName_); 1833 inter_copy_keyvaluepair(U, L2, L2_cache_i, L, vt_, mode_, upName_);
1791 lua_pop( L, 1); // pop value (next round) 1834 lua_pop( L, 1); // pop value (next round)
1792 } 1835 }
1793 STACK_CHECK( L, 0); 1836 STACK_CHECK( L, 0);
@@ -1803,6 +1846,8 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta
1803 return true; 1846 return true;
1804} 1847}
1805 1848
1849// #################################################################################################
1850
1806/* 1851/*
1807* Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove 1852* Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove
1808* the original value. 1853* the original value.
@@ -1813,7 +1858,7 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta
1813* 1858*
1814* Returns true if value was pushed, false if its type is non-supported. 1859* Returns true if value was pushed, false if its type is non-supported.
1815*/ 1860*/
1816bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) 1861bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_)
1817{ 1862{
1818 bool ret{ true }; 1863 bool ret{ true };
1819 int val_type = lua_type( L, i); 1864 int val_type = lua_type( L, i);
@@ -1824,7 +1869,7 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in
1824 1869
1825 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); 1870 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END));
1826 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1871 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1827 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[vt])); 1872 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[static_cast<int>(vt_)]));
1828 1873
1829 // Non-POD can be skipped if its metatable contains { __lanesignore = true } 1874 // Non-POD can be skipped if its metatable contains { __lanesignore = true }
1830 if( ((1 << val_type) & pod_mask) == 0) 1875 if( ((1 << val_type) & pod_mask) == 0)
@@ -1894,11 +1939,11 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in
1894 /* The following types are not allowed as table keys */ 1939 /* The following types are not allowed as table keys */
1895 1940
1896 case LUA_TUSERDATA: 1941 case LUA_TUSERDATA:
1897 ret = inter_copy_userdata( U, L2, L2_cache_i, L, i, vt, mode_, upName_); 1942 ret = inter_copy_userdata(U, L2, L2_cache_i, L, i, vt_, mode_, upName_);
1898 break; 1943 break;
1899 1944
1900 case LUA_TNIL: 1945 case LUA_TNIL:
1901 if( vt == VT_KEY) 1946 if (vt_ == VT::KEY)
1902 { 1947 {
1903 ret = false; 1948 ret = false;
1904 break; 1949 break;
@@ -1907,11 +1952,11 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in
1907 break; 1952 break;
1908 1953
1909 case LUA_TFUNCTION: 1954 case LUA_TFUNCTION:
1910 ret = inter_copy_function( U, L2, L2_cache_i, L, i, vt, mode_, upName_); 1955 ret = inter_copy_function(U, L2, L2_cache_i, L, i, vt_, mode_, upName_);
1911 break; 1956 break;
1912 1957
1913 case LUA_TTABLE: 1958 case LUA_TTABLE:
1914 ret = inter_copy_table( U, L2, L2_cache_i, L, i, vt, mode_, upName_); 1959 ret = inter_copy_table(U, L2, L2_cache_i, L, i, vt_, mode_, upName_);
1915 break; 1960 break;
1916 1961
1917 /* The following types cannot be copied */ 1962 /* The following types cannot be copied */
@@ -1973,7 +2018,7 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode
1973 { 2018 {
1974 sprintf( tmpBuf, "arg_%d", j); 2019 sprintf( tmpBuf, "arg_%d", j);
1975 } 2020 }
1976 copyok = inter_copy_one( U, L2, top_L2 + 1, L, i, VT_NORMAL, mode_, pBuf); // ... cache {}n 2021 copyok = inter_copy_one(U, L2, top_L2 + 1, L, i, VT::NORMAL, mode_, pBuf); // ... cache {}n
1977 if( !copyok) 2022 if( !copyok)
1978 { 2023 {
1979 break; 2024 break;
@@ -2019,7 +2064,7 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa
2019 lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_)); 2064 lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_));
2020 STACK_CHECK( L, 1); 2065 STACK_CHECK( L, 1);
2021 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later 2066 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later
2022 return ( mode_ == eLM_LaneBody) ? lua_error( L) : 1; 2067 return (mode_ == LookupMode::LaneBody) ? lua_error(L) : 1;
2023 } 2068 }
2024 lua_getglobal( L2, "package"); 2069 lua_getglobal( L2, "package");
2025 if( !lua_isnil( L2, -1)) // package library not loaded: do nothing 2070 if( !lua_isnil( L2, -1)) // package library not loaded: do nothing
@@ -2029,7 +2074,7 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa
2029 // but don't copy it anyway, as the function names change depending on the slot index! 2074 // but don't copy it anyway, as the function names change depending on the slot index!
2030 // users should provide an on_state_create function to setup custom loaders instead 2075 // users should provide an on_state_create function to setup custom loaders instead
2031 // don't copy package.preload in keeper states (they don't know how to translate functions) 2076 // don't copy package.preload in keeper states (they don't know how to translate functions)
2032 char const* entries[] = { "path", "cpath", (mode_ == eLM_LaneBody) ? "preload" : nullptr /*, (LUA_VERSION_NUM == 501) ? "loaders" : "searchers"*/, nullptr }; 2077 char const* entries[] = { "path", "cpath", (mode_ == LookupMode::LaneBody) ? "preload" : nullptr /*, (LUA_VERSION_NUM == 501) ? "loaders" : "searchers"*/, nullptr };
2033 for( i = 0; entries[i]; ++ i) 2078 for( i = 0; entries[i]; ++ i)
2034 { 2079 {
2035 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "package.%s\n" INDENT_END, entries[i])); 2080 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "package.%s\n" INDENT_END, entries[i]));
diff --git a/src/tools.h b/src/tools.h
index 5e6ce78..c1a8534 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -19,13 +19,13 @@ void luaG_dump( lua_State* L);
19void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_); 19void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_);
20void push_registry_subtable( lua_State* L, UniqueKey key_); 20void push_registry_subtable( lua_State* L, UniqueKey key_);
21 21
22enum e_vt 22enum class VT
23{ 23{
24 VT_NORMAL, 24 NORMAL,
25 VT_KEY, 25 KEY,
26 VT_METATABLE 26 METATABLE
27}; 27};
28bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_); 28bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_);
29 29
30// ################################################################################################ 30// ################################################################################################
31 31
diff --git a/src/universe.h b/src/universe.h
index a2ad5f5..3ee0868 100644
--- a/src/universe.h
+++ b/src/universe.h
@@ -13,13 +13,13 @@ extern "C" {
13 13
14#include <mutex> 14#include <mutex>
15 15
16// ################################################################################################
17
16// forwards 18// forwards
17struct DeepPrelude; 19struct DeepPrelude;
18struct Keepers; 20struct Keepers;
19class Lane; 21class Lane;
20 22
21// ################################################################################################
22
23/* 23/*
24* Do we want to activate full lane tracking feature? (EXPERIMENTAL) 24* Do we want to activate full lane tracking feature? (EXPERIMENTAL)
25*/ 25*/
@@ -167,6 +167,8 @@ struct Universe
167 int volatile selfdestructing_count{ 0 }; 167 int volatile selfdestructing_count{ 0 };
168}; 168};
169 169
170// ################################################################################################
171
170Universe* universe_get(lua_State* L); 172Universe* universe_get(lua_State* L);
171Universe* universe_create(lua_State* L); 173Universe* universe_create(lua_State* L);
172void universe_store(lua_State* L, Universe* U); 174void universe_store(lua_State* L, Universe* U);