aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-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
13 files changed, 234 insertions, 186 deletions
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);