diff options
-rw-r--r-- | deep_test/deep_test.cpp | 8 | ||||
-rw-r--r-- | docs/index.html | 12 | ||||
-rw-r--r-- | src/cancel.cpp | 49 | ||||
-rw-r--r-- | src/cancel.h | 16 | ||||
-rw-r--r-- | src/deep.cpp | 40 | ||||
-rw-r--r-- | src/deep.h | 18 | ||||
-rw-r--r-- | src/keeper.cpp | 16 | ||||
-rw-r--r-- | src/keeper.h | 2 | ||||
-rw-r--r-- | src/lanes.cpp | 86 | ||||
-rw-r--r-- | src/linda.cpp | 16 | ||||
-rw-r--r-- | src/state.cpp | 6 | ||||
-rw-r--r-- | src/state.h | 16 | ||||
-rw-r--r-- | src/tools.cpp | 139 | ||||
-rw-r--r-- | src/tools.h | 10 | ||||
-rw-r--r-- | src/universe.h | 6 |
15 files changed, 244 insertions, 196 deletions
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp index d7ecd33..7c8180f 100644 --- a/deep_test/deep_test.cpp +++ b/deep_test/deep_test.cpp | |||
@@ -19,26 +19,26 @@ static void* deep_test_id( lua_State* L, DeepOp op_) | |||
19 | { | 19 | { |
20 | switch( op_) | 20 | switch( op_) |
21 | { | 21 | { |
22 | case eDO_new: | 22 | case DeepOp::New: |
23 | { | 23 | { |
24 | MyDeepUserdata* deep_test = new MyDeepUserdata; | 24 | MyDeepUserdata* deep_test = new MyDeepUserdata; |
25 | return deep_test; | 25 | return deep_test; |
26 | } | 26 | } |
27 | 27 | ||
28 | case eDO_delete: | 28 | case DeepOp::Delete: |
29 | { | 29 | { |
30 | MyDeepUserdata* deep_test = static_cast<MyDeepUserdata*>(lua_touserdata( L, 1)); | 30 | MyDeepUserdata* deep_test = static_cast<MyDeepUserdata*>(lua_touserdata( L, 1)); |
31 | delete deep_test; | 31 | delete deep_test; |
32 | return nullptr; | 32 | return nullptr; |
33 | } | 33 | } |
34 | 34 | ||
35 | case eDO_metatable: | 35 | case DeepOp::Metatable: |
36 | { | 36 | { |
37 | luaL_getmetatable( L, "deep"); // mt | 37 | luaL_getmetatable( L, "deep"); // mt |
38 | return nullptr; | 38 | return nullptr; |
39 | } | 39 | } |
40 | 40 | ||
41 | case eDO_module: | 41 | case DeepOp::Module: |
42 | return (void*)"deep_test"; | 42 | return (void*)"deep_test"; |
43 | 43 | ||
44 | default: | 44 | default: |
diff --git a/docs/index.html b/docs/index.html index f8124c7..24fa4ef 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -1669,10 +1669,10 @@ int luaD_new_clonable( lua_State* L) | |||
1669 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, DeepOp op_);</pre></td></tr></table> | 1669 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> void* idfunc( lua_State* L, DeepOp op_);</pre></td></tr></table> |
1670 | <tt>op_</tt> can be one of: | 1670 | <tt>op_</tt> can be one of: |
1671 | <ul> | 1671 | <ul> |
1672 | <li><tt>eDO_new</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li> | 1672 | <li><tt>DeepOp::New</tt>: requests the creation of a new object, whose pointer is returned. Said object must derive from <tt>DeepPrelude</tt>.</li> |
1673 | <li><tt>eDO_delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> | 1673 | <li><tt>DeepOp::Delete</tt>: receives this same pointer on the stack as a light userdata, and should cleanup the object.</li> |
1674 | <li><tt>eDO_metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>eDO_metatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li> | 1674 | <li><tt>DeepOp::Metatable</tt>: should build a metatable for the object. Don't cache the metatable yourself, Lanes takes care of it (<tt>DeepOp::Metatable</tt> should only be invoked once per state). Just push the metatable on the stack.</li> |
1675 | <li><tt>eDO_module</tt>: requests the name of the module that exports the idfunc, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the idfunc pointer is still held.</li> | 1675 | <li><tt>DeepOp::Module</tt>: requests the name of the module that exports the idfunc, to be returned. It is necessary so that Lanes can require it in any lane state that receives a userdata. This is to prevent crashes in situations where the module could be unloaded while the idfunc pointer is still held.</li> |
1676 | </ul> | 1676 | </ul> |
1677 | Take a look at <tt>linda_id</tt> in <tt>lanes.cpp</tt> or <tt>deep_test_id</tt> in <tt>deep_test.cpp</tt>. | 1677 | Take a look at <tt>linda_id</tt> in <tt>lanes.cpp</tt> or <tt>deep_test_id</tt> in <tt>deep_test.cpp</tt>. |
1678 | </li> | 1678 | </li> |
@@ -1686,13 +1686,13 @@ int luaD_new_clonable( lua_State* L) | |||
1686 | </p> | 1686 | </p> |
1687 | 1687 | ||
1688 | <p> | 1688 | <p> |
1689 | Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(eDO_delete)</tt> and aren't considered by reference counting. The rationale is the following: | 1689 | Deep userdata in transit inside keeper states (sent in a linda but not yet consumed) don't call <tt>idfunc(DeepOp::Delete)</tt> and aren't considered by reference counting. The rationale is the following: |
1690 | <br /> | 1690 | <br /> |
1691 | If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0. | 1691 | If some non-keeper state holds a deep userdata for some deep object, then even if the keeper collects its own deep userdata, it shouldn't be cleaned up since the refcount is not 0. |
1692 | <br /> | 1692 | <br /> |
1693 | OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>idfunc()</tt> is never called from a keeper state. | 1693 | OTOH, if a keeper state holds the last deep userdata for some deep object, then no lane can do actual work with it. Deep userdata's <tt>idfunc()</tt> is never called from a keeper state. |
1694 | <br /> | 1694 | <br /> |
1695 | Therefore, Lanes can just call <tt>idfunc(eDO_delete)</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in keeper states now hold stale pointers. | 1695 | Therefore, Lanes can just call <tt>idfunc(DeepOp::Delete)</tt> when the last non-keeper-held deep userdata is collected, as long as it doesn't do the same in a keeper state after that, since any remaining deep userdata in keeper states now hold stale pointers. |
1696 | </p> | 1696 | </p> |
1697 | 1697 | ||
1698 | <p> | 1698 | <p> |
diff --git a/src/cancel.cpp b/src/cancel.cpp index 07c316a..4667f07 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp | |||
@@ -189,7 +189,7 @@ CancelResult thread_cancel(lua_State* L, Lane* lane_, CancelOp op_, double secs_ | |||
189 | 189 | ||
190 | // signal the linda the wake up the thread so that it can react to the cancel query | 190 | // signal the linda the wake up the thread so that it can react to the cancel query |
191 | // let us hope we never land here with a pointer on a linda that has been destroyed... | 191 | // let us hope we never land here with a pointer on a linda that has been destroyed... |
192 | if (op_ == CO_Soft) | 192 | if (op_ == CancelOp::Soft) |
193 | { | 193 | { |
194 | return thread_cancel_soft(lane_, secs_, force_); | 194 | return thread_cancel_soft(lane_, secs_, force_); |
195 | } | 195 | } |
@@ -203,45 +203,46 @@ CancelResult thread_cancel(lua_State* L, Lane* lane_, CancelOp op_, double secs_ | |||
203 | // > 0: the mask | 203 | // > 0: the mask |
204 | // = 0: soft | 204 | // = 0: soft |
205 | // < 0: hard | 205 | // < 0: hard |
206 | static CancelOp which_op( lua_State* L, int idx_) | 206 | static 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 | ||
37 | enum CancelOp | 37 | enum 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) | |||
113 | static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mode_) | 113 | static 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; |
@@ -21,19 +21,19 @@ extern "C" { | |||
21 | // forwards | 21 | // forwards |
22 | struct Universe; | 22 | struct Universe; |
23 | 23 | ||
24 | enum LookupMode | 24 | enum 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 | ||
31 | enum DeepOp | 31 | enum 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 | ||
39 | using luaG_IdFunction = void*(*)( lua_State* L, DeepOp op_); | 39 | using 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 |
15 | enum class LookupMode; | ||
15 | struct Universe; | 16 | struct Universe; |
16 | enum LookupMode; | ||
17 | 17 | ||
18 | struct Keeper | 18 | struct 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 | ||
8 | void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State *L); | 5 | // forwards |
6 | struct Universe; | ||
7 | |||
8 | void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); | ||
9 | 9 | ||
10 | // ################################################################################################ | 10 | // ################################################################################################ |
11 | 11 | ||
12 | lua_State* create_state( Universe* U, lua_State* from_); | 12 | lua_State* create_state(Universe* U, lua_State* from_); |
13 | lua_State* luaG_newstate( Universe* U, lua_State* _from, char const* libs); | 13 | lua_State* luaG_newstate(Universe* U, lua_State* _from, char const* libs); |
14 | 14 | ||
15 | // ################################################################################################ | 15 | // ################################################################################################ |
16 | 16 | ||
17 | void initialize_on_state_create( Universe* U, lua_State* L); | 17 | void initialize_on_state_create(Universe* U, lua_State* L); |
18 | void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMode mode_); | 18 | void 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 | ||
304 | static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out) | 304 | // ################################################################################################# |
305 | |||
306 | static 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/ |
312 | static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull }; | 314 | static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull }; |
313 | 315 | ||
316 | // ################################################################################################# | ||
317 | |||
314 | // inspired from tconcat() in ltablib.c | 318 | // inspired from tconcat() in ltablib.c |
315 | static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) | 319 | static 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 | ||
421 | static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) | 427 | // ################################################################################################# |
428 | |||
429 | static 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 |
655 | static int func_lookup_sentinel( lua_State* L) | 669 | static 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 |
662 | static int table_lookup_sentinel( lua_State* L) | 677 | static 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 |
668 | static int userdata_clone_sentinel( lua_State* L) | 685 | static 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 | }; |
1145 | static char const* vt_names[] = | 1170 | static 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 | |||
1168 | static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) | 1197 | static 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 | |||
1373 | static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) | 1406 | static 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 | ||
1422 | static 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 | |||
1457 | static 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 | ||
1605 | static 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 | |||
1644 | static 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 | ||
1653 | static 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 | |||
1694 | static 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 | ||
1746 | static 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 | |||
1789 | static 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 | */ |
1816 | bool 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_) | 1861 | bool 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); | |||
19 | void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_); | 19 | void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_); |
20 | void push_registry_subtable( lua_State* L, UniqueKey key_); | 20 | void push_registry_subtable( lua_State* L, UniqueKey key_); |
21 | 21 | ||
22 | enum e_vt | 22 | enum class VT |
23 | { | 23 | { |
24 | VT_NORMAL, | 24 | NORMAL, |
25 | VT_KEY, | 25 | KEY, |
26 | VT_METATABLE | 26 | METATABLE |
27 | }; | 27 | }; |
28 | bool 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_); | 28 | bool 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 |
17 | struct DeepPrelude; | 19 | struct DeepPrelude; |
18 | struct Keepers; | 20 | struct Keepers; |
19 | class Lane; | 21 | class 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 | |||
170 | Universe* universe_get(lua_State* L); | 172 | Universe* universe_get(lua_State* L); |
171 | Universe* universe_create(lua_State* L); | 173 | Universe* universe_create(lua_State* L); |
172 | void universe_store(lua_State* L, Universe* U); | 174 | void universe_store(lua_State* L, Universe* U); |