aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cancel.cpp7
-rw-r--r--src/compat.cpp35
-rw-r--r--src/deep.cpp40
-rw-r--r--src/deep.h4
-rw-r--r--src/keeper.cpp16
-rw-r--r--src/keeper.h2
-rw-r--r--src/lanes.cpp20
-rw-r--r--src/lanes_private.h4
-rw-r--r--src/linda.cpp10
-rw-r--r--src/macros_and_utils.h18
-rw-r--r--src/state.cpp29
-rw-r--r--src/state.h3
-rw-r--r--src/threading.cpp12
-rw-r--r--src/threading.h1
-rw-r--r--src/tools.cpp85
-rw-r--r--src/tools.h14
-rw-r--r--src/universe.cpp8
17 files changed, 157 insertions, 151 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp
index 437a6f0..e08e975 100644
--- a/src/cancel.cpp
+++ b/src/cancel.cpp
@@ -1,6 +1,6 @@
1/* 1/*
2-- 2--
3-- CANCEL.C 3-- CANCEL.CPP
4-- 4--
5-- Lane cancellation support 5-- Lane cancellation support
6-- 6--
@@ -9,7 +9,7 @@
9--[[ 9--[[
10=============================================================================== 10===============================================================================
11 11
12Copyright (C) 2011-2019 Benoit Germain <bnt.germain@gmail.com> 12Copyright (C) 2011-2024 Benoit Germain <bnt.germain@gmail.com>
13 13
14Permission is hereby granted, free of charge, to any person obtaining a copy 14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal 15of this software and associated documentation files (the "Software"), to deal
@@ -35,9 +35,6 @@ THE SOFTWARE.
35 35
36#include "cancel.h" 36#include "cancel.h"
37 37
38// #include <assert.h>
39//#include <string.h>
40
41#include "lanes_private.h" 38#include "lanes_private.h"
42#include "threading.h" 39#include "threading.h"
43#include "tools.h" 40#include "tools.h"
diff --git a/src/compat.cpp b/src/compat.cpp
index 47fe37e..8acab25 100644
--- a/src/compat.cpp
+++ b/src/compat.cpp
@@ -1,6 +1,6 @@
1/* 1/*
2 * ############################################################################################### 2 * ###############################################################################################
3 * ######################################### Lua 5.1/5.2 ######################################### 3 * ####################################### Lua 5.1/5.2/5.3 #######################################
4 * ############################################################################################### 4 * ###############################################################################################
5 */ 5 */
6#include "compat.h" 6#include "compat.h"
@@ -9,7 +9,12 @@
9/* 9/*
10** Copied from Lua 5.2 loadlib.c 10** Copied from Lua 5.2 loadlib.c
11*/ 11*/
12// ################################################################################################
13// ################################################################################################
12#if LUA_VERSION_NUM == 501 14#if LUA_VERSION_NUM == 501
15// ################################################################################################
16// ################################################################################################
17
13static int luaL_getsubtable (lua_State *L, int idx, const char *fname) 18static int luaL_getsubtable (lua_State *L, int idx, const char *fname)
14{ 19{
15 lua_getfield(L, idx, fname); 20 lua_getfield(L, idx, fname);
@@ -26,6 +31,8 @@ static int luaL_getsubtable (lua_State *L, int idx, const char *fname)
26 } 31 }
27} 32}
28 33
34// ################################################################################################
35
29void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) 36void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb)
30{ 37{
31 lua_pushcfunction(L, openf); 38 lua_pushcfunction(L, openf);
@@ -43,24 +50,30 @@ void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int
43} 50}
44#endif // LUA_VERSION_NUM 51#endif // LUA_VERSION_NUM
45 52
53// ################################################################################################
54// ################################################################################################
46#if LUA_VERSION_NUM < 504 55#if LUA_VERSION_NUM < 504
56// ################################################################################################
57// ################################################################################################
47 58
48void* lua_newuserdatauv( lua_State* L, size_t sz, int nuvalue) 59void* lua_newuserdatauv( lua_State* L, size_t sz, int nuvalue)
49{ 60{
50 ASSERT_L( nuvalue <= 1); 61 ASSERT_L( nuvalue <= 1);
51 return lua_newuserdata( L, sz); 62 return lua_newuserdata(L, sz);
52} 63}
53 64
65// ################################################################################################
66
54// push on stack uservalue #n of full userdata at idx 67// push on stack uservalue #n of full userdata at idx
55int lua_getiuservalue(lua_State* L, int idx, int n) 68int lua_getiuservalue(lua_State* L, int idx, int n)
56{ 69{
57 // full userdata can have only 1 uservalue before 5.4 70 // full userdata can have only 1 uservalue before 5.4
58 if( n > 1) 71 if( n > 1)
59 { 72 {
60 lua_pushnil( L); 73 lua_pushnil(L);
61 return LUA_TNONE; 74 return LUA_TNONE;
62 } 75 }
63 lua_getuservalue( L, idx); 76 lua_getuservalue(L, idx);
64 77
65#if LUA_VERSION_NUM == 501 78#if LUA_VERSION_NUM == 501
66 /* default environment is not a nil (see lua_getfenv) */ 79 /* default environment is not a nil (see lua_getfenv) */
@@ -68,30 +81,32 @@ int lua_getiuservalue(lua_State* L, int idx, int n)
68 if (lua_rawequal(L, -2, -1) || lua_rawequal(L, -2, LUA_GLOBALSINDEX)) 81 if (lua_rawequal(L, -2, -1) || lua_rawequal(L, -2, LUA_GLOBALSINDEX))
69 { 82 {
70 lua_pop(L, 2); 83 lua_pop(L, 2);
71 lua_pushnil( L); 84 lua_pushnil(L);
72 85
73 return LUA_TNONE; 86 return LUA_TNONE;
74 } 87 }
75 lua_pop(L, 1); /* remove package */ 88 lua_pop(L, 1); /* remove package */
76#endif 89#endif
77 90
78 return lua_type( L, -1); 91 return lua_type(L, -1);
79} 92}
80 93
94// ################################################################################################
95
81// pop stack top, sets it a uservalue #n of full userdata at idx 96// pop stack top, sets it a uservalue #n of full userdata at idx
82int lua_setiuservalue( lua_State* L, int idx, int n) 97int lua_setiuservalue(lua_State* L, int idx, int n)
83{ 98{
84 if( n > 1 99 if( n > 1
85#if LUA_VERSION_NUM == 501 100#if LUA_VERSION_NUM == 501
86 || lua_type( L, -1) != LUA_TTABLE 101 || lua_type(L, -1) != LUA_TTABLE
87#endif 102#endif
88 ) 103 )
89 { 104 {
90 lua_pop( L, 1); 105 lua_pop(L, 1);
91 return 0; 106 return 0;
92 } 107 }
93 108
94 (void) lua_setuservalue( L, idx); 109 std::ignore = lua_setuservalue(L, idx);
95 return 1; // I guess anything non-0 is ok 110 return 1; // I guess anything non-0 is ok
96} 111}
97 112
diff --git a/src/deep.cpp b/src/deep.cpp
index ac2905e..55063b3 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -1,5 +1,5 @@
1/* 1/*
2 * DEEP.C Copyright (c) 2017, Benoit Germain 2 * DEEP.CPP Copyright (c) 2024, Benoit Germain
3 * 3 *
4 * Deep userdata support, separate in its own source file to help integration 4 * Deep userdata support, separate in its own source file to help integration
5 * without enforcing a Lanes dependency 5 * without enforcing a Lanes dependency
@@ -9,7 +9,7 @@
9=============================================================================== 9===============================================================================
10 10
11Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> 11Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com>
12 2011-17 Benoit Germain <bnt.germain@gmail.com> 12 2011-24 Benoit Germain <bnt.germain@gmail.com>
13 13
14Permission is hereby granted, free of charge, to any person obtaining a copy 14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal 15of this software and associated documentation files (the "Software"), to deal
@@ -41,13 +41,6 @@ THE SOFTWARE.
41 41
42#include <bit> 42#include <bit>
43#include <cassert> 43#include <cassert>
44#include <ctype.h>
45#include <stdio.h>
46#include <string.h>
47#include <stdlib.h>
48#if !defined(__APPLE__)
49#include <malloc.h>
50#endif
51 44
52/*-- Metatable copying --*/ 45/*-- Metatable copying --*/
53 46
@@ -73,7 +66,7 @@ static constexpr UniqueKey DEEP_PROXY_CACHE_KEY{ 0x05773d6fc26be106ull };
73* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 66* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
74* Pops the both values off the stack. 67* Pops the both values off the stack.
75*/ 68*/
76static void set_deep_lookup( lua_State* L) 69static void set_deep_lookup(lua_State* L)
77{ 70{
78 STACK_GROW( L, 3); 71 STACK_GROW( L, 3);
79 STACK_CHECK_START_REL(L, 2); // a b 72 STACK_CHECK_START_REL(L, 2); // a b
@@ -88,11 +81,13 @@ static void set_deep_lookup( lua_State* L)
88 STACK_CHECK( L, 0); 81 STACK_CHECK( L, 0);
89} 82}
90 83
84// ################################################################################################
85
91/* 86/*
92* Pops the key (metatable or idfunc) off the stack, and replaces with the 87* Pops the key (metatable or idfunc) off the stack, and replaces with the
93* deep lookup value (idfunc/metatable/nil). 88* deep lookup value (idfunc/metatable/nil).
94*/ 89*/
95static void get_deep_lookup( lua_State* L) 90static void get_deep_lookup(lua_State* L)
96{ 91{
97 STACK_GROW( L, 1); 92 STACK_GROW( L, 1);
98 STACK_CHECK_START_REL(L, 1); // a 93 STACK_CHECK_START_REL(L, 1); // a
@@ -106,11 +101,13 @@ static void get_deep_lookup( lua_State* L)
106 STACK_CHECK( L, 1); 101 STACK_CHECK( L, 1);
107} 102}
108 103
104// ################################################################################################
105
109/* 106/*
110* Return the registered ID function for 'index' (deep userdata proxy), 107* Return the registered ID function for 'index' (deep userdata proxy),
111* or nullptr if 'index' is not a deep userdata proxy. 108* or nullptr if 'index' is not a deep userdata proxy.
112*/ 109*/
113static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mode_) 110static inline luaG_IdFunction get_idfunc(lua_State* L, int index, LookupMode mode_)
114{ 111{
115 // when looking inside a keeper, we are 100% sure the object is a deep userdata 112 // when looking inside a keeper, we are 100% sure the object is a deep userdata
116 if (mode_ == LookupMode::FromKeeper) 113 if (mode_ == LookupMode::FromKeeper)
@@ -142,8 +139,9 @@ static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mo
142 } 139 }
143} 140}
144 141
142// ################################################################################################
145 143
146void free_deep_prelude( lua_State* L, DeepPrelude* prelude_) 144void free_deep_prelude(lua_State* L, DeepPrelude* prelude_)
147{ 145{
148 ASSERT_L(prelude_->idfunc); 146 ASSERT_L(prelude_->idfunc);
149 STACK_CHECK_START_REL(L, 0); 147 STACK_CHECK_START_REL(L, 0);
@@ -154,6 +152,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_)
154 STACK_CHECK(L, 0); 152 STACK_CHECK(L, 0);
155} 153}
156 154
155// ################################################################################################
157 156
158/* 157/*
159 * void= mt.__gc( proxy_ud ) 158 * void= mt.__gc( proxy_ud )
@@ -161,7 +160,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_)
161 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0. 160 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0.
162 * 161 *
163 */ 162 */
164static int deep_userdata_gc( lua_State* L) 163static int deep_userdata_gc(lua_State* L)
165{ 164{
166 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) }; 165 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) };
167 DeepPrelude* p = *proxy; 166 DeepPrelude* p = *proxy;
@@ -193,6 +192,7 @@ static int deep_userdata_gc( lua_State* L)
193 return 0; 192 return 0;
194} 193}
195 194
195// ################################################################################################
196 196
197/* 197/*
198 * Push a proxy userdata on the stack. 198 * Push a proxy userdata on the stack.
@@ -203,7 +203,7 @@ static int deep_userdata_gc( lua_State* L)
203 * used in this Lua state (metatable, registring it). Otherwise, increments the 203 * used in this Lua state (metatable, registring it). Otherwise, increments the
204 * reference count. 204 * reference count.
205 */ 205 */
206char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, LookupMode mode_) 206char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_)
207{ 207{
208 // Check if a proxy already exists 208 // Check if a proxy already exists
209 push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC 209 push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC
@@ -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, DeepOp::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 {
@@ -348,6 +348,8 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
348 return nullptr; 348 return nullptr;
349} 349}
350 350
351// ################################################################################################
352
351/* 353/*
352* Create a deep userdata 354* Create a deep userdata
353* 355*
@@ -370,7 +372,7 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
370* 372*
371* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' 373* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()'
372*/ 374*/
373int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_) 375int luaG_newdeepuserdata(Dest L, luaG_IdFunction idfunc, int nuv_)
374{ 376{
375 STACK_GROW( L, 1); 377 STACK_GROW( L, 1);
376 STACK_CHECK_START_REL(L, 0); 378 STACK_CHECK_START_REL(L, 0);
@@ -409,6 +411,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_)
409 return 1; 411 return 1;
410} 412}
411 413
414// ################################################################################################
412 415
413/* 416/*
414* Access deep userdata through a proxy. 417* Access deep userdata through a proxy.
@@ -430,6 +433,7 @@ DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index)
430 return *proxy; 433 return *proxy;
431} 434}
432 435
436// ################################################################################################
433 437
434/* 438/*
435 * Copy deep userdata between two separate Lua states (from L to L2) 439 * Copy deep userdata between two separate Lua states (from L to L2)
@@ -438,7 +442,7 @@ DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index)
438 * the id function of the copied value, or nullptr for non-deep userdata 442 * the id function of the copied value, or nullptr for non-deep userdata
439 * (not copied) 443 * (not copied)
440 */ 444 */
441bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 445bool copydeep(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_)
442{ 446{
443 luaG_IdFunction const idfunc { get_idfunc(L, i, mode_) }; 447 luaG_IdFunction const idfunc { get_idfunc(L, i, mode_) };
444 if (idfunc == nullptr) 448 if (idfunc == nullptr)
diff --git a/src/deep.h b/src/deep.h
index c09af23..6cf33ec 100644
--- a/src/deep.h
+++ b/src/deep.h
@@ -54,8 +54,8 @@ struct DeepPrelude
54 std::atomic<int> m_refcount{ 0 }; 54 std::atomic<int> m_refcount{ 0 };
55}; 55};
56 56
57char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, LookupMode mode_); 57char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_);
58void free_deep_prelude( lua_State* L, DeepPrelude* prelude_); 58void free_deep_prelude( lua_State* L, DeepPrelude* prelude_);
59 59
60LANES_API int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_); 60LANES_API int luaG_newdeepuserdata(Dest L, luaG_IdFunction idfunc, int nuv_);
61LANES_API DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index); 61LANES_API DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index);
diff --git a/src/keeper.cpp b/src/keeper.cpp
index 0aea18e..9718bda 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -14,7 +14,7 @@
14 --[[ 14 --[[
15 =============================================================================== 15 ===============================================================================
16 16
17 Copyright (C) 2011-2023 Benoit Germain <bnt.germain@gmail.com> 17 Copyright (C) 2011-2024 Benoit Germain <bnt.germain@gmail.com>
18 18
19 Permission is hereby granted, free of charge, to any person obtaining a copy 19 Permission is hereby granted, free of charge, to any person obtaining a copy
20 of this software and associated documentation files (the "Software"), to deal 20 of this software and associated documentation files (the "Software"), to deal
@@ -207,10 +207,10 @@ static void push_table(lua_State* L, int idx_)
207 207
208// ################################################################################################## 208// ##################################################################################################
209 209
210int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, uintptr_t magic_) 210int keeper_push_linda_storage(Universe* U, Dest L, void* ptr_, uintptr_t magic_)
211{ 211{
212 Keeper* const K{ which_keeper(U->keepers, magic_) }; 212 Keeper* const K{ which_keeper(U->keepers, magic_) };
213 lua_State* const KL{ K ? K->L : nullptr }; 213 Source const KL{ K ? K->L : nullptr };
214 if (KL == nullptr) 214 if (KL == nullptr)
215 return 0; 215 return 0;
216 STACK_GROW(KL, 4); 216 STACK_GROW(KL, 4);
@@ -412,7 +412,7 @@ int keepercall_limit(lua_State* L)
412 // set the new limit 412 // set the new limit
413 fifo->limit = limit; 413 fifo->limit = limit;
414 // return 0 or 1 value 414 // return 0 or 1 value
415 return lua_gettop( L); 415 return lua_gettop(L);
416} 416}
417 417
418// ################################################################################################## 418// ##################################################################################################
@@ -485,7 +485,7 @@ int keepercall_set(lua_State* L)
485 lua_insert(L, 3); // fifos key fifotbl [val [, ...]] 485 lua_insert(L, 3); // fifos key fifotbl [val [, ...]]
486 fifo_push(L, fifo, count); // fifos key fifotbl 486 fifo_push(L, fifo, count); // fifos key fifotbl
487 } 487 }
488 return should_wake_writers ? (lua_pushboolean( L, 1), 1) : 0; 488 return should_wake_writers ? (lua_pushboolean(L, 1), 1) : 0;
489} 489}
490 490
491// ################################################################################################## 491// ##################################################################################################
@@ -717,7 +717,7 @@ void init_keepers(Universe* U, lua_State* L)
717 if (!lua_isnil(L, -1)) 717 if (!lua_isnil(L, -1))
718 { 718 {
719 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately 719 // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately
720 if (luaG_inter_copy_package(U, L, K, -1, LookupMode::ToKeeper)) 720 if (luaG_inter_copy_package(U, Source{ L }, Dest{ K }, -1, LookupMode::ToKeeper))
721 { 721 {
722 // if something went wrong, the error message is at the top of the stack 722 // if something went wrong, the error message is at the top of the stack
723 lua_remove(L, -2); // error_msg 723 lua_remove(L, -2); // error_msg
@@ -840,7 +840,7 @@ int keeper_call(Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, voi
840 840
841 lua_pushlightuserdata(K, linda); 841 lua_pushlightuserdata(K, linda);
842 842
843 if ((args == 0) || luaG_inter_copy(U, L, K, args, LookupMode::ToKeeper) == 0) // L->K 843 if ((args == 0) || luaG_inter_copy(U, Source{ L }, Dest{ K }, args, LookupMode::ToKeeper) == 0) // L->K
844 { 844 {
845 lua_call(K, 1 + args, LUA_MULTRET); 845 lua_call(K, 1 + args, LUA_MULTRET);
846 retvals = lua_gettop(K) - Ktos; 846 retvals = lua_gettop(K) - Ktos;
@@ -848,7 +848,7 @@ int keeper_call(Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, voi
848 // this may interrupt a lane, causing the destruction of the underlying OS thread 848 // this may interrupt a lane, causing the destruction of the underlying OS thread
849 // after this, another lane making use of this keeper can get an error code from the mutex-locking function 849 // after this, another lane making use of this keeper can get an error code from the mutex-locking function
850 // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) 850 // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread)
851 if ((retvals > 0) && luaG_inter_move(U, K, L, retvals, LookupMode::FromKeeper) != 0) // K->L 851 if ((retvals > 0) && luaG_inter_move(U, Source{ K }, Dest{ L }, retvals, LookupMode::FromKeeper) != 0) // K->L
852 { 852 {
853 retvals = -1; 853 retvals = -1;
854 } 854 }
diff --git a/src/keeper.h b/src/keeper.h
index ba5a57b..89fa2ab 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -42,7 +42,7 @@ Keeper* which_keeper(Keepers* keepers_, uintptr_t magic_);
42Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_); 42Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_);
43void keeper_release(Keeper* K_); 43void keeper_release(Keeper* K_);
44void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_); 44void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_);
45int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, uintptr_t magic_); 45int keeper_push_linda_storage(Universe* U, Dest L, void* ptr_, uintptr_t magic_);
46 46
47using keeper_api_t = lua_CFunction; 47using keeper_api_t = lua_CFunction;
48#define KEEPER_API(_op) keepercall_##_op 48#define KEEPER_API(_op) keepercall_##_op
diff --git a/src/lanes.cpp b/src/lanes.cpp
index cf443f2..3d0c70d 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -1027,7 +1027,7 @@ LUAG_FUNC(lane_new)
1027 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); 1027 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed));
1028 1028
1029 // populate with selected libraries at the same time 1029 // populate with selected libraries at the same time
1030 lua_State* const L2{ luaG_newstate(U, L, libs_str) }; // L // L2 1030 lua_State* const L2{ luaG_newstate(U, Source{ L }, libs_str) }; // L // L2
1031 1031
1032 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1032 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1033 Lane* const lane{ new (U) Lane{ U, L2 } }; 1033 Lane* const lane{ new (U) Lane{ U, L2 } };
@@ -1134,7 +1134,7 @@ LUAG_FUNC(lane_new)
1134 { 1134 {
1135 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END)); 1135 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END));
1136 // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack 1136 // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack
1137 (void) luaG_inter_copy_package(U, L, L2, package_idx, LookupMode::LaneBody); 1137 std::ignore = luaG_inter_copy_package(U, Source{ L }, Dest{ L2 }, package_idx, LookupMode::LaneBody);
1138 } 1138 }
1139 1139
1140 // modules to require in the target lane *before* the function is transfered! 1140 // modules to require in the target lane *before* the function is transfered!
@@ -1150,7 +1150,7 @@ LUAG_FUNC(lane_new)
1150 } 1150 }
1151 1151
1152 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil 1152 lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil
1153 while( lua_next(L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" 1153 while (lua_next(L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname"
1154 { 1154 {
1155 if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired) 1155 if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired)
1156 { 1156 {
@@ -1176,7 +1176,7 @@ LUAG_FUNC(lane_new)
1176 if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode 1176 if (lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode
1177 { 1177 {
1178 // propagate error to main state if any 1178 // propagate error to main state if any
1179 luaG_inter_move(U, L2, L, 1, LookupMode::LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error 1179 luaG_inter_move(U, Source{ L2 }, Dest{ L }, 1, LookupMode::LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error
1180 raise_lua_error(L); 1180 raise_lua_error(L);
1181 } 1181 }
1182 // after requiring the module, register the functions it exported in our name<->function database 1182 // after requiring the module, register the functions it exported in our name<->function database
@@ -1209,7 +1209,7 @@ LUAG_FUNC(lane_new)
1209 lua_pushglobaltable(L2); // _G 1209 lua_pushglobaltable(L2); // _G
1210 while( lua_next(L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v 1210 while( lua_next(L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v
1211 { 1211 {
1212 luaG_inter_copy(U, L, L2, 2, LookupMode::LaneBody); // _G k v 1212 luaG_inter_copy(U, Source{ L }, Dest{ L2 }, 2, LookupMode::LaneBody); // _G k v
1213 // assign it in L2's globals table 1213 // assign it in L2's globals table
1214 lua_rawset(L2, -3); // _G 1214 lua_rawset(L2, -3); // _G
1215 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] k 1215 lua_pop(L, 1); // func libs priority globals package required gc_cb [... args ...] k
@@ -1227,7 +1227,7 @@ LUAG_FUNC(lane_new)
1227 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); 1227 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END));
1228 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); 1228 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed));
1229 lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func 1229 lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func
1230 int const res{ luaG_inter_move(U, L, L2, 1, LookupMode::LaneBody) };// func libs priority globals package required gc_cb [... args ...] // func 1230 int const res{ luaG_inter_move(U, Source{ L }, Dest{ L2 }, 1, LookupMode::LaneBody) }; // func libs priority globals package required gc_cb [... args ...] // func
1231 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); 1231 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed));
1232 if (res != 0) 1232 if (res != 0)
1233 { 1233 {
@@ -1253,7 +1253,7 @@ LUAG_FUNC(lane_new)
1253 int res; 1253 int res;
1254 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); 1254 DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END));
1255 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); 1255 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed));
1256 res = luaG_inter_move(U, L, L2, nargs, LookupMode::LaneBody); // func libs priority globals package required gc_cb // func [... args ...] 1256 res = luaG_inter_move(U, Source{ L }, Dest{ L2 }, nargs, LookupMode::LaneBody); // func libs priority globals package required gc_cb // func [... args ...]
1257 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); 1257 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed));
1258 if (res != 0) 1258 if (res != 0)
1259 { 1259 {
@@ -1418,7 +1418,7 @@ LUAG_FUNC(thread_join)
1418 case Lane::Done: 1418 case Lane::Done:
1419 { 1419 {
1420 int const n{ lua_gettop(L2) }; // whole L2 stack 1420 int const n{ lua_gettop(L2) }; // whole L2 stack
1421 if ((n > 0) && (luaG_inter_move(U, L2, L, n, LookupMode::LaneBody) != 0)) 1421 if ((n > 0) && (luaG_inter_move(U, Source{ L2 }, Dest{ L }, n, LookupMode::LaneBody) != 0))
1422 { 1422 {
1423 return luaL_error(L, "tried to copy unsupported types"); 1423 return luaL_error(L, "tried to copy unsupported types");
1424 } 1424 }
@@ -1432,7 +1432,7 @@ LUAG_FUNC(thread_join)
1432 STACK_GROW(L, 3); 1432 STACK_GROW(L, 3);
1433 lua_pushnil(L); 1433 lua_pushnil(L);
1434 // 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 ... 1434 // 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 ...
1435 if (luaG_inter_move(U, L2, L, n, LookupMode::LaneBody) != 0) // nil "err" [trace] 1435 if (luaG_inter_move(U, Source{ L2 }, Dest{ L }, n, LookupMode::LaneBody) != 0) // nil "err" [trace]
1436 { 1436 {
1437 return luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n)); 1437 return luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n));
1438 } 1438 }
@@ -1832,7 +1832,7 @@ LUAG_FUNC(configure)
1832 STACK_CHECK(L, 2); 1832 STACK_CHECK(L, 2);
1833 1833
1834 { 1834 {
1835 char const* errmsg{ push_deep_proxy(L, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep 1835 char const* errmsg{ push_deep_proxy(Dest{ L }, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep
1836 if (errmsg != nullptr) 1836 if (errmsg != nullptr)
1837 { 1837 {
1838 return luaL_error(L, errmsg); 1838 return luaL_error(L, errmsg);
diff --git a/src/lanes_private.h b/src/lanes_private.h
index 3ed52fe..0fcbbfc 100644
--- a/src/lanes_private.h
+++ b/src/lanes_private.h
@@ -98,6 +98,6 @@ static constexpr UniqueKey LANE_POINTER_REGKEY{ 0xB3022205633743BCull }; // used
98// 'Lane' are malloc/free'd and the handle only carries a pointer. 98// 'Lane' are malloc/free'd and the handle only carries a pointer.
99// This is not deep userdata since the handle's not portable among lanes. 99// This is not deep userdata since the handle's not portable among lanes.
100// 100//
101#define lua_toLane( L, i) (*((Lane**) luaL_checkudata( L, i, "Lane"))) 101#define lua_toLane(L, i) (*((Lane**) luaL_checkudata( L, i, "Lane")))
102 102
103int push_thread_status( lua_State* L, Lane* s); 103int push_thread_status(lua_State* L, Lane* s);
diff --git a/src/linda.cpp b/src/linda.cpp
index fb74abe..39977bc 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -804,7 +804,7 @@ LUAG_FUNC(linda_concat)
804LUAG_FUNC(linda_dump) 804LUAG_FUNC(linda_dump)
805{ 805{
806 Linda* const linda{ lua_toLinda<false>(L, 1) }; 806 Linda* const linda{ lua_toLinda<false>(L, 1) };
807 return keeper_push_linda_storage(linda->U, L, linda, linda->hashSeed()); 807 return keeper_push_linda_storage(linda->U, Dest{ L }, linda, linda->hashSeed());
808} 808}
809 809
810// ################################################################################################# 810// #################################################################################################
@@ -816,7 +816,7 @@ LUAG_FUNC(linda_dump)
816LUAG_FUNC(linda_towatch) 816LUAG_FUNC(linda_towatch)
817{ 817{
818 Linda* const linda{ lua_toLinda<false>(L, 1) }; 818 Linda* const linda{ lua_toLinda<false>(L, 1) };
819 int pushed{ keeper_push_linda_storage(linda->U, L, linda, linda->hashSeed()) }; 819 int pushed{ keeper_push_linda_storage(linda->U, Dest{ L }, linda, linda->hashSeed()) };
820 if (pushed == 0) 820 if (pushed == 0)
821 { 821 {
822 // if the linda is empty, don't return nil 822 // if the linda is empty, don't return nil
@@ -1009,11 +1009,11 @@ static void* linda_id( lua_State* L, DeepOp op_)
1009 */ 1009 */
1010LUAG_FUNC(linda) 1010LUAG_FUNC(linda)
1011{ 1011{
1012 int const top = lua_gettop(L); 1012 int const top{ lua_gettop(L) };
1013 luaL_argcheck(L, top <= 2, top, "too many arguments"); 1013 luaL_argcheck(L, top <= 2, top, "too many arguments");
1014 if (top == 1) 1014 if (top == 1)
1015 { 1015 {
1016 int const t = lua_type(L, 1); 1016 int const t{ lua_type(L, 1) };
1017 luaL_argcheck(L, t == LUA_TSTRING || t == LUA_TNUMBER, 1, "wrong parameter (should be a string or a number)"); 1017 luaL_argcheck(L, t == LUA_TSTRING || t == LUA_TNUMBER, 1, "wrong parameter (should be a string or a number)");
1018 } 1018 }
1019 else if (top == 2) 1019 else if (top == 2)
@@ -1021,5 +1021,5 @@ LUAG_FUNC(linda)
1021 luaL_checktype(L, 1, LUA_TSTRING); 1021 luaL_checktype(L, 1, LUA_TSTRING);
1022 luaL_checktype(L, 2, LUA_TNUMBER); 1022 luaL_checktype(L, 2, LUA_TNUMBER);
1023 } 1023 }
1024 return luaG_newdeepuserdata(L, linda_id, 0); 1024 return luaG_newdeepuserdata(Dest{ L }, linda_id, 0);
1025} 1025}
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h
index 997b452..47ce90c 100644
--- a/src/macros_and_utils.h
+++ b/src/macros_and_utils.h
@@ -44,8 +44,8 @@ extern char const* debugspew_indent;
44 44
45#else // NDEBUG 45#else // NDEBUG
46 46
47#define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);} 47#define _ASSERT_L(L, cond_) if( (cond_) == 0) { (void) luaL_error(L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);}
48#define STACK_DUMP( L) luaG_dump( L) 48#define STACK_DUMP(L) luaG_dump(L)
49 49
50class StackChecker 50class StackChecker
51{ 51{
@@ -172,3 +172,17 @@ T* lua_newuserdatauv(lua_State* L, int nuvalue_)
172} 172}
173 173
174using lua_Duration = std::chrono::template duration<lua_Number>; 174using lua_Duration = std::chrono::template duration<lua_Number>;
175
176// #################################################################################################
177
178template <typename T, auto = []{}>
179struct Unique
180{
181 T m_val;
182 Unique() = default;
183 operator T() const { return m_val; }
184 explicit Unique(T b_) : m_val{ b_ } {}
185};
186
187using Source = Unique<lua_State*>;
188using Dest = Unique<lua_State*>;
diff --git a/src/state.cpp b/src/state.cpp
index 512009a..6a9ada7 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -1,5 +1,5 @@
1/* 1/*
2* STATE.C 2* STATE.CPP
3* 3*
4* Lua tools to support Lanes. 4* Lua tools to support Lanes.
5*/ 5*/
@@ -31,20 +31,11 @@ THE SOFTWARE.
31=============================================================================== 31===============================================================================
32*/ 32*/
33 33
34#include <stdio.h> 34#include "state.h"
35#include <assert.h> 35
36#include <string.h>
37#include <ctype.h>
38#include <stdlib.h>
39#if !defined(__APPLE__)
40#include <malloc.h>
41#endif // __APPLE__
42
43#include "compat.h"
44#include "macros_and_utils.h"
45#include "universe.h"
46#include "tools.h"
47#include "lanes.h" 36#include "lanes.h"
37#include "tools.h"
38#include "universe.h"
48 39
49// ################################################################################################ 40// ################################################################################################
50 41
@@ -194,9 +185,9 @@ static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char con
194 185
195 186
196// just like lua_xmove, args are (from, to) 187// just like lua_xmove, args are (from, to)
197static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) 188static void copy_one_time_settings(Universe* U, Source L, Dest L2)
198{ 189{
199 STACK_GROW( L, 2); 190 STACK_GROW(L, 2);
200 STACK_CHECK_START_REL(L, 0); 191 STACK_CHECK_START_REL(L, 0);
201 STACK_CHECK_START_REL(L2, 0); 192 STACK_CHECK_START_REL(L2, 0);
202 193
@@ -326,11 +317,11 @@ void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMod
326* *NOT* called for keeper states! 317* *NOT* called for keeper states!
327* 318*
328*/ 319*/
329lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) 320lua_State* luaG_newstate(Universe* U, Source from_, char const* libs_)
330{ 321{
331 lua_State* L = create_state( U, from_); 322 Dest const L{ create_state(U, from_) };
332 323
333 STACK_GROW( L, 2); 324 STACK_GROW(L, 2);
334 STACK_CHECK_START_ABS(L, 0); 325 STACK_CHECK_START_ABS(L, 0);
335 326
336 // copy the universe as a light userdata (only the master state holds the full userdata) 327 // copy the universe as a light userdata (only the master state holds the full userdata)
diff --git a/src/state.h b/src/state.h
index 0e069da..2601f77 100644
--- a/src/state.h
+++ b/src/state.h
@@ -3,6 +3,7 @@
3#include "macros_and_utils.h" 3#include "macros_and_utils.h"
4 4
5// forwards 5// forwards
6enum class LookupMode;
6class Universe; 7class Universe;
7 8
8void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); 9void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L);
@@ -10,7 +11,7 @@ void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L);
10// ################################################################################################ 11// ################################################################################################
11 12
12lua_State* create_state(Universe* U, lua_State* from_); 13lua_State* create_state(Universe* U, lua_State* from_);
13lua_State* luaG_newstate(Universe* U, lua_State* _from, char const* libs); 14lua_State* luaG_newstate(Universe* U, Source _from, char const* libs);
14 15
15// ################################################################################################ 16// ################################################################################################
16 17
diff --git a/src/threading.cpp b/src/threading.cpp
index 4d210d6..d278bb1 100644
--- a/src/threading.cpp
+++ b/src/threading.cpp
@@ -1,6 +1,6 @@
1/* 1/*
2 * THREADING.C Copyright (c) 2007-08, Asko Kauppi 2 * THREADING.CPP Copyright (c) 2007-08, Asko Kauppi
3 * Copyright (C) 2009-19, Benoit Germain 3 * Copyright (C) 2009-24, Benoit Germain
4 * 4 *
5 * Lua Lanes OS threading specific code. 5 * Lua Lanes OS threading specific code.
6 * 6 *
@@ -12,7 +12,7 @@
12=============================================================================== 12===============================================================================
13 13
14Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> 14Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com>
15Copyright (C) 2009-14, Benoit Germain <bnt.germain@gmail.com> 15Copyright (C) 2009-24, Benoit Germain <bnt.germain@gmail.com>
16 16
17Permission is hereby granted, free of charge, to any person obtaining a copy 17Permission is hereby granted, free of charge, to any person obtaining a copy
18of this software and associated documentation files (the "Software"), to deal 18of this software and associated documentation files (the "Software"), to deal
@@ -47,12 +47,6 @@ THE SOFTWARE.
47 47
48#endif // __linux__ 48#endif // __linux__
49 49
50#include <stdio.h>
51#include <stdlib.h>
52#include <assert.h>
53#include <errno.h>
54#include <math.h>
55
56#include "threading.h" 50#include "threading.h"
57 51
58#if !defined( PLATFORM_XBOX) && !defined( PLATFORM_WIN32) && !defined( PLATFORM_POCKETPC) 52#if !defined( PLATFORM_XBOX) && !defined( PLATFORM_WIN32) && !defined( PLATFORM_POCKETPC)
diff --git a/src/threading.h b/src/threading.h
index f38b2de..fc35730 100644
--- a/src/threading.h
+++ b/src/threading.h
@@ -2,7 +2,6 @@
2 2
3#include "platform.h" 3#include "platform.h"
4 4
5#include <time.h>
6#include <thread> 5#include <thread>
7 6
8#define THREADAPI_WINDOWS 1 7#define THREADAPI_WINDOWS 1
diff --git a/src/tools.cpp b/src/tools.cpp
index ac5f7c5..07f9ae6 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -31,24 +31,12 @@ THE SOFTWARE.
31=============================================================================== 31===============================================================================
32*/ 32*/
33 33
34#include <stdio.h>
35#include <assert.h>
36#include <string.h>
37#include <ctype.h>
38#include <stdlib.h>
39#if !defined(__APPLE__)
40#include <malloc.h>
41#endif // __APPLE__
42
43#include "tools.h" 34#include "tools.h"
44#include "compat.h" 35
45#include "universe.h" 36#include "universe.h"
46#include "keeper.h"
47#include "lanes.h"
48#include "uniquekey.h"
49 37
50// functions implemented in deep.c 38// functions implemented in deep.c
51extern bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_); 39extern bool copydeep(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_);
52extern void push_registry_subtable( lua_State* L, UniqueKey key_); 40extern void push_registry_subtable( lua_State* L, UniqueKey key_);
53 41
54DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); 42DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+");
@@ -554,10 +542,10 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U)
554/* 542/*
555 * create a "fully.qualified.name" <-> function equivalence database 543 * create a "fully.qualified.name" <-> function equivalence database
556 */ 544 */
557void populate_func_lookup_table( lua_State* L, int _i, char const* name_) 545void populate_func_lookup_table(lua_State* L, int i_, char const* name_)
558{ 546{
559 int const ctx_base = lua_gettop( L) + 1; 547 int const ctx_base = lua_gettop(L) + 1;
560 int const in_base = lua_absindex( L, _i); 548 int const in_base = lua_absindex(L, i_);
561 int start_depth = 0; 549 int start_depth = 0;
562 DEBUGSPEW_CODE( Universe* U = universe_get( L)); 550 DEBUGSPEW_CODE( Universe* U = universe_get( L));
563 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); 551 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr"));
@@ -765,7 +753,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char
765/* 753/*
766 * Push a looked-up table, or nothing if we found nothing 754 * Push a looked-up table, or nothing if we found nothing
767 */ 755 */
768static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, char const* upName_) 756static bool lookup_table(Dest L2, Source L, int i, LookupMode mode_, char const* upName_)
769{ 757{
770 // get the name of the table we want to send 758 // get the name of the table we want to send
771 size_t len; 759 size_t len;
@@ -775,7 +763,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
775 return false; 763 return false;
776 } 764 }
777 // push the equivalent table in the destination's stack, retrieved from the lookup table 765 // push the equivalent table in the destination's stack, retrieved from the lookup table
778 STACK_CHECK_START_REL(L2, 0); // L // L2 766 STACK_CHECK_START_REL(L2, 0); // L // L2
779 STACK_GROW( L2, 3); // up to 3 slots are necessary on error 767 STACK_GROW( L2, 3); // up to 3 slots are necessary on error
780 switch( mode_) 768 switch( mode_)
781 { 769 {
@@ -785,34 +773,34 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
785 773
786 case LookupMode::ToKeeper: 774 case LookupMode::ToKeeper:
787 // push a sentinel closure that holds the lookup name as upvalue 775 // push a sentinel closure that holds the lookup name as upvalue
788 lua_pushlstring( L2, fqn, len); // "f.q.n" 776 lua_pushlstring(L2, fqn, len); // "f.q.n"
789 lua_pushcclosure( L2, table_lookup_sentinel, 1); // f 777 lua_pushcclosure(L2, table_lookup_sentinel, 1); // f
790 break; 778 break;
791 779
792 case LookupMode::LaneBody: 780 case LookupMode::LaneBody:
793 case LookupMode::FromKeeper: 781 case LookupMode::FromKeeper:
794 LOOKUP_REGKEY.pushValue(L2); // {} 782 LOOKUP_REGKEY.pushValue(L2); // {}
795 STACK_CHECK( L2, 1); 783 STACK_CHECK(L2, 1);
796 ASSERT_L( lua_istable( L2, -1)); 784 ASSERT_L(lua_istable(L2, -1));
797 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 785 lua_pushlstring(L2, fqn, len); // {} "f.q.n"
798 lua_rawget( L2, -2); // {} t 786 lua_rawget(L2, -2); // {} t
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) 787 // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead)
800 // but not when we extract something out of a keeper, as there is nothing to clone! 788 // but not when we extract something out of a keeper, as there is nothing to clone!
801 if (lua_isnil(L2, -1) && mode_ == LookupMode::LaneBody) 789 if (lua_isnil(L2, -1) && mode_ == LookupMode::LaneBody)
802 { 790 {
803 lua_pop( L2, 2); // 791 lua_pop(L2, 2); //
804 STACK_CHECK( L2, 0); 792 STACK_CHECK(L2, 0);
805 return false; 793 return false;
806 } 794 }
807 else if( !lua_istable( L2, -1)) 795 else if( !lua_istable(L2, -1))
808 { 796 {
809 char const* from, *to; 797 char const* from, *to;
810 lua_getglobal( L, "decoda_name"); // ... t ... decoda_name 798 lua_getglobal(L, "decoda_name"); // ... t ... decoda_name
811 from = lua_tostring( L, -1); 799 from = lua_tostring(L, -1);
812 lua_pop( L, 1); // ... t ... 800 lua_pop(L, 1); // ... t ...
813 lua_getglobal( L2, "decoda_name"); // {} t decoda_name 801 lua_getglobal(L2, "decoda_name"); // {} t decoda_name
814 to = lua_tostring( L2, -1); 802 to = lua_tostring( L2, -1);
815 lua_pop( L2, 1); // {} t 803 lua_pop(L2, 1); // {} t
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 804 // 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
817 (void) luaL_error( 805 (void) luaL_error(
818 (mode_ == LookupMode::FromKeeper) ? L2 : L 806 (mode_ == LookupMode::FromKeeper) ? L2 : L
@@ -823,7 +811,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c
823 ); 811 );
824 return false; 812 return false;
825 } 813 }
826 lua_remove( L2, -2); // t 814 lua_remove(L2, -2); // t
827 break; 815 break;
828 } 816 }
829 STACK_CHECK( L2, 1); 817 STACK_CHECK( L2, 1);
@@ -1194,7 +1182,7 @@ static int buf_writer( lua_State* L, void const* b, size_t size, void* ud)
1194 1182
1195// ################################################################################################# 1183// #################################################################################################
1196 1184
1197static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 1185static void copy_func(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_)
1198{ 1186{
1199 int n, needToPush; 1187 int n, needToPush;
1200 luaL_Buffer B; 1188 luaL_Buffer B;
@@ -1348,7 +1336,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1348 * 1336 *
1349 * Always pushes a function to 'L2'. 1337 * Always pushes a function to 'L2'.
1350 */ 1338 */
1351static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 1339static void copy_cached_func(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_)
1352{ 1340{
1353 FuncSubType funcSubType; 1341 FuncSubType funcSubType;
1354 /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // nullptr for LuaJIT-fast && bytecode functions 1342 /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // nullptr for LuaJIT-fast && bytecode functions
@@ -1403,7 +1391,7 @@ static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta
1403 1391
1404// ################################################################################################# 1392// #################################################################################################
1405 1393
1406static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 1394static bool push_cached_metatable(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_)
1407{ 1395{
1408 STACK_CHECK_START_REL(L, 0); 1396 STACK_CHECK_START_REL(L, 0);
1409 if( lua_getmetatable( L, i)) // ... mt 1397 if( lua_getmetatable( L, i)) // ... mt
@@ -1454,7 +1442,7 @@ static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lu
1454 1442
1455// ################################################################################################# 1443// #################################################################################################
1456 1444
1457static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, VT vt_, LookupMode mode_, char const* upName_) 1445static void inter_copy_keyvaluepair(Universe* U, Dest L2, int L2_cache_i, Source L, VT vt_, LookupMode mode_, char const* upName_)
1458{ 1446{
1459 int val_i = lua_gettop(L); 1447 int val_i = lua_gettop(L);
1460 int key_i = val_i - 1; 1448 int key_i = val_i - 1;
@@ -1526,7 +1514,7 @@ static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i,
1526*/ 1514*/
1527static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; 1515static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull };
1528 1516
1529static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int source_i_, LookupMode mode_, char const* upName_) 1517static bool copyclone(Universe* U, Dest L2, int L2_cache_i, Source L, int source_i_, LookupMode mode_, char const* upName_)
1530{ 1518{
1531 void* const source = lua_touserdata( L, source_i_); 1519 void* const source = lua_touserdata( L, source_i_);
1532 source_i_ = lua_absindex( L, source_i_); 1520 source_i_ = lua_absindex( L, source_i_);
@@ -1641,7 +1629,7 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L,
1641 1629
1642// ################################################################################################# 1630// #################################################################################################
1643 1631
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_) 1632static bool inter_copy_userdata(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_)
1645{ 1633{
1646 STACK_CHECK_START_REL(L, 0); 1634 STACK_CHECK_START_REL(L, 0);
1647 STACK_CHECK_START_REL(L2, 0); 1635 STACK_CHECK_START_REL(L2, 0);
@@ -1691,7 +1679,7 @@ static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_
1691 1679
1692// ################################################################################################# 1680// #################################################################################################
1693 1681
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_) 1682static bool inter_copy_function(Universe* U, Dest L2, int L2_cache_i, Source L, int source_i_, VT vt_, LookupMode mode_, char const* upName_)
1695{ 1683{
1696 if (vt_ == VT::KEY) 1684 if (vt_ == VT::KEY)
1697 { 1685 {
@@ -1786,7 +1774,7 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_
1786 1774
1787// ################################################################################################# 1775// #################################################################################################
1788 1776
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_) 1777static bool inter_copy_table(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_)
1790{ 1778{
1791 if (vt_ == VT::KEY) 1779 if (vt_ == VT::KEY)
1792 { 1780 {
@@ -1858,7 +1846,7 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta
1858* 1846*
1859* Returns true if value was pushed, false if its type is non-supported. 1847* Returns true if value was pushed, false if its type is non-supported.
1860*/ 1848*/
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_) 1849bool inter_copy_one(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_)
1862{ 1850{
1863 bool ret{ true }; 1851 bool ret{ true };
1864 int val_type = lua_type( L, i); 1852 int val_type = lua_type( L, i);
@@ -1974,6 +1962,8 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in
1974 return ret; 1962 return ret;
1975} 1963}
1976 1964
1965// #################################################################################################
1966
1977/* 1967/*
1978* Akin to 'lua_xmove' but copies values between _any_ Lua states. 1968* Akin to 'lua_xmove' but copies values between _any_ Lua states.
1979* 1969*
@@ -1981,7 +1971,7 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in
1981* 1971*
1982* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'. 1972* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'.
1983*/ 1973*/
1984int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode mode_) 1974int luaG_inter_copy(Universe* U, Source L, Dest L2, int n, LookupMode mode_)
1985{ 1975{
1986 int top_L = lua_gettop(L); // ... {}n 1976 int top_L = lua_gettop(L); // ... {}n
1987 int top_L2 = lua_gettop(L2); // ... 1977 int top_L2 = lua_gettop(L2); // ...
@@ -2043,15 +2033,16 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode
2043 return -2; 2033 return -2;
2044} 2034}
2045 2035
2036// #################################################################################################
2046 2037
2047int luaG_inter_move(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode mode_) 2038int luaG_inter_move(Universe* U, Source L, Dest L2, int n, LookupMode mode_)
2048{ 2039{
2049 int ret = luaG_inter_copy( U, L, L2, n, mode_); 2040 int ret = luaG_inter_copy( U, L, L2, n, mode_);
2050 lua_pop( L, (int) n); 2041 lua_pop( L, (int) n);
2051 return ret; 2042 return ret;
2052} 2043}
2053 2044
2054int luaG_inter_copy_package(Universe* U, lua_State* L, lua_State* L2, int package_idx_, LookupMode mode_) 2045int luaG_inter_copy_package(Universe* U, Source L, Dest L2, int package_idx_, LookupMode mode_)
2055{ 2046{
2056 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); 2047 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END));
2057 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); 2048 DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed));
diff --git a/src/tools.h b/src/tools.h
index 7d9aaab..8e95a4f 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -25,19 +25,19 @@ enum class VT
25 KEY, 25 KEY,
26 METATABLE 26 METATABLE
27}; 27};
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_); 28bool inter_copy_one(Universe* U, Dest L2, int L2_cache_i, Source L, int i, VT vt_, LookupMode mode_, char const* upName_);
29 29
30// ################################################################################################ 30// ################################################################################################
31 31
32int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int package_idx_, LookupMode mode_); 32int luaG_inter_copy_package(Universe* U, Source L, Dest L2, int package_idx_, LookupMode mode_);
33 33
34int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode mode_); 34int luaG_inter_copy(Universe* U, Source L, Dest L2, int n, LookupMode mode_);
35int luaG_inter_move(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode mode_); 35int luaG_inter_move(Universe* U, Source L, Dest L2, int n, LookupMode mode_);
36 36
37int luaG_nameof( lua_State* L); 37int luaG_nameof(lua_State* L);
38 38
39void populate_func_lookup_table( lua_State* L, int _i, char const* _name); 39void populate_func_lookup_table(lua_State* L, int _i, char const* _name);
40void initialize_allocator_function( Universe* U, lua_State* L); 40void initialize_allocator_function(Universe* U, lua_State* L);
41 41
42// ################################################################################################ 42// ################################################################################################
43 43
diff --git a/src/universe.cpp b/src/universe.cpp
index 290e547..4c53987 100644
--- a/src/universe.cpp
+++ b/src/universe.cpp
@@ -80,7 +80,7 @@ Universe* universe_create(lua_State* L)
80 U->Universe::Universe(); 80 U->Universe::Universe();
81 STACK_CHECK_START_REL(L, 1); 81 STACK_CHECK_START_REL(L, 1);
82 UNIVERSE_FULL_REGKEY.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 82 UNIVERSE_FULL_REGKEY.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); });
83 UNIVERSE_LIGHT_REGKEY.setValue(L, [U](lua_State* L) { lua_pushlightuserdata( L, U); }); 83 UNIVERSE_LIGHT_REGKEY.setValue(L, [U](lua_State* L) { lua_pushlightuserdata(L, U); });
84 STACK_CHECK(L, 1); 84 STACK_CHECK(L, 1);
85 return U; 85 return U;
86} 86}
@@ -91,8 +91,8 @@ void universe_store(lua_State* L, Universe* U)
91{ 91{
92 ASSERT_L(!U || universe_get(L) == nullptr); 92 ASSERT_L(!U || universe_get(L) == nullptr);
93 STACK_CHECK_START_REL(L, 0); 93 STACK_CHECK_START_REL(L, 0);
94 UNIVERSE_LIGHT_REGKEY.setValue(L, [U](lua_State* L) { U ? lua_pushlightuserdata( L, U) : lua_pushnil( L); }); 94 UNIVERSE_LIGHT_REGKEY.setValue(L, [U](lua_State* L) { U ? lua_pushlightuserdata(L, U) : lua_pushnil(L); });
95 STACK_CHECK( L, 0); 95 STACK_CHECK(L, 0);
96} 96}
97 97
98// ################################################################################################ 98// ################################################################################################
@@ -101,6 +101,6 @@ Universe* universe_get(lua_State* L)
101{ 101{
102 STACK_CHECK_START_REL(L, 0); 102 STACK_CHECK_START_REL(L, 0);
103 Universe* const universe{ UNIVERSE_LIGHT_REGKEY.readLightUserDataValue<Universe>(L) }; 103 Universe* const universe{ UNIVERSE_LIGHT_REGKEY.readLightUserDataValue<Universe>(L) };
104 STACK_CHECK( L, 0); 104 STACK_CHECK(L, 0);
105 return universe; 105 return universe;
106} 106}