aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lanes.cpp170
1 files changed, 87 insertions, 83 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index d549449..1a4e8b7 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -189,7 +189,7 @@ static void lane_main(Lane* lane);
189void Lane::startThread(int priority_) 189void Lane::startThread(int priority_)
190{ 190{
191 m_thread = std::jthread([this]() { lane_main(this); }); 191 m_thread = std::jthread([this]() { lane_main(this); });
192 if (priority_ != THREAD_PRIO_DEFAULT) 192 if (priority_ != kThreadPrioDefault)
193 { 193 {
194 JTHREAD_SET_PRIORITY(m_thread, priority_, U->m_sudo); 194 JTHREAD_SET_PRIORITY(m_thread, priority_, U->m_sudo);
195 } 195 }
@@ -218,8 +218,8 @@ static void securize_debug_threadname(lua_State* L, Lane* lane_)
218 218
219#if ERROR_FULL_STACK 219#if ERROR_FULL_STACK
220[[nodiscard]] static int lane_error(lua_State* L); 220[[nodiscard]] static int lane_error(lua_State* L);
221// crc64/we of string "STACKTRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 221// xxh64 of string "kStackTraceRegKey" generated at https://www.pelock.com/products/hash-calculator
222static constexpr RegistryUniqueKey STACKTRACE_REGKEY{ 0x534AF7D3226A429Full }; 222static constexpr RegistryUniqueKey kStackTraceRegKey{ 0x3F327747CACAA904ull };
223#endif // ERROR_FULL_STACK 223#endif // ERROR_FULL_STACK
224 224
225/* 225/*
@@ -230,8 +230,8 @@ static constexpr RegistryUniqueKey STACKTRACE_REGKEY{ 0x534AF7D3226A429Full };
230* error (and maybe stack trace) parameters to the finalizer functions would 230* error (and maybe stack trace) parameters to the finalizer functions would
231* anyways complicate that approach. 231* anyways complicate that approach.
232*/ 232*/
233// crc64/we of string "FINALIZER_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 233// xxh64 of string "kFinalizerRegKey" generated at https://www.pelock.com/products/hash-calculator
234static constexpr RegistryUniqueKey FINALIZER_REGKEY{ 0x188FCCB8BF348E09ull }; 234static constexpr RegistryUniqueKey kFinalizerRegKey{ 0xFE936BFAA718FEEAull };
235 235
236// ################################################################################################# 236// #################################################################################################
237 237
@@ -260,13 +260,13 @@ static void push_finalizers_table(lua_State* L)
260 STACK_GROW(L, 3); 260 STACK_GROW(L, 3);
261 STACK_CHECK_START_REL(L, 0); 261 STACK_CHECK_START_REL(L, 0);
262 262
263 FINALIZER_REGKEY.pushValue(L); // ? 263 kFinalizerRegKey.pushValue(L); // ?
264 if (lua_isnil(L, -1)) // nil? 264 if (lua_isnil(L, -1)) // nil?
265 { 265 {
266 lua_pop(L, 1); // 266 lua_pop(L, 1); //
267 // store a newly created table in the registry, but leave it on the stack too 267 // store a newly created table in the registry, but leave it on the stack too
268 lua_newtable(L); // t 268 lua_newtable(L); // t
269 FINALIZER_REGKEY.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // t 269 kFinalizerRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // t
270 } 270 }
271 STACK_CHECK(L, 1); 271 STACK_CHECK(L, 1);
272} 272}
@@ -312,12 +312,12 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
312 // fetch the call stack table from the registry where the handler stored it 312 // fetch the call stack table from the registry where the handler stored it
313 STACK_GROW(L, 1); 313 STACK_GROW(L, 1);
314 // yields nil if no stack was generated (in case of cancellation for example) 314 // yields nil if no stack was generated (in case of cancellation for example)
315 STACKTRACE_REGKEY.pushValue(L); // err trace|nil 315 kStackTraceRegKey.pushValue(L); // err trace|nil
316 STACK_CHECK(L, 1); 316 STACK_CHECK(L, 1);
317 317
318 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed 318 // For cancellation the error message is kCancelError, and a stack trace isn't placed
319 // For other errors, the message can be whatever was thrown, and we should have a stack trace table 319 // For other errors, the message can be whatever was thrown, and we should have a stack trace table
320 LUA_ASSERT(L, lua_type(L, 1 + stk_base_) == (CANCEL_ERROR.equals(L, stk_base_) ? LUA_TNIL : LUA_TTABLE)); 320 LUA_ASSERT(L, lua_type(L, 1 + stk_base_) == (kCancelError.equals(L, stk_base_) ? LUA_TNIL : LUA_TTABLE));
321 // Just leaving the stack trace table on the stack is enough to get it through to the master. 321 // Just leaving the stack trace table on the stack is enough to get it through to the master.
322 break; 322 break;
323 } 323 }
@@ -326,8 +326,8 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
326 case LUA_ERRMEM: // memory allocation error (handler not called) 326 case LUA_ERRMEM: // memory allocation error (handler not called)
327 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) 327 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition)
328 default: 328 default:
329 // we should have a single value which is either a string (the error message) or CANCEL_ERROR 329 // we should have a single value which is either a string (the error message) or kCancelError
330 LUA_ASSERT(L, (lua_gettop(L) == stk_base_) && ((lua_type(L, stk_base_) == LUA_TSTRING) || CANCEL_ERROR.equals(L, stk_base_))); 330 LUA_ASSERT(L, (lua_gettop(L) == stk_base_) && ((lua_type(L, stk_base_) == LUA_TSTRING) || kCancelError.equals(L, stk_base_)));
331 break; 331 break;
332 } 332 }
333} 333}
@@ -349,7 +349,7 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
349 349
350[[nodiscard]] static int run_finalizers(lua_State* L, int lua_rc_) 350[[nodiscard]] static int run_finalizers(lua_State* L, int lua_rc_)
351{ 351{
352 FINALIZER_REGKEY.pushValue(L); // ... finalizers? 352 kFinalizerRegKey.pushValue(L); // ... finalizers?
353 if (lua_isnil(L, -1)) 353 if (lua_isnil(L, -1))
354 { 354 {
355 lua_pop(L, 1); 355 lua_pop(L, 1);
@@ -373,7 +373,7 @@ static void push_stack_trace(lua_State* L, int rc_, int stk_base_)
373 LUA_ASSERT(L, finalizers_index == 2 || finalizers_index == 3); 373 LUA_ASSERT(L, finalizers_index == 2 || finalizers_index == 3);
374 //char const* err_msg = lua_tostring(L, 1); 374 //char const* err_msg = lua_tostring(L, 1);
375 lua_pushvalue(L, 1); // ... finalizers lane_error finalizer err_msg 375 lua_pushvalue(L, 1); // ... finalizers lane_error finalizer err_msg
376 // note we don't always have a stack trace for example when CANCEL_ERROR, or when we got an error that doesn't call our handler, such as LUA_ERRMEM 376 // note we don't always have a stack trace for example when kCancelError, or when we got an error that doesn't call our handler, such as LUA_ERRMEM
377 if (finalizers_index == 3) 377 if (finalizers_index == 3)
378 { 378 {
379 lua_pushvalue(L, 2); // ... finalizers lane_error finalizer err_msg stack_trace 379 lua_pushvalue(L, 2); // ... finalizers lane_error finalizer err_msg stack_trace
@@ -633,8 +633,8 @@ LUAG_FUNC( set_singlethreaded)
633*/ 633*/
634#if ERROR_FULL_STACK 634#if ERROR_FULL_STACK
635 635
636// crc64/we of string "EXTENDED_STACKTRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 636// xxh64 of string "kExtendedStackTraceRegKey" generated at https://www.pelock.com/products/hash-calculator
637static constexpr RegistryUniqueKey EXTENDED_STACKTRACE_REGKEY{ 0x2357C69A7C92C936ull }; // used as registry key 637static constexpr RegistryUniqueKey kExtendedStackTraceRegKey{ 0x38147AD48FB426E2ull }; // used as registry key
638 638
639LUAG_FUNC( set_error_reporting) 639LUAG_FUNC( set_error_reporting)
640{ 640{
@@ -648,7 +648,7 @@ LUAG_FUNC( set_error_reporting)
648 return luaL_error(L, "unsupported error reporting model %s", mode); 648 return luaL_error(L, "unsupported error reporting model %s", mode);
649 } 649 }
650 650
651 EXTENDED_STACKTRACE_REGKEY.setValue(L, [extended](lua_State* L) { lua_pushboolean(L, extended ? 1 : 0); }); 651 kExtendedStackTraceRegKey.setValue(L, [extended](lua_State* L) { lua_pushboolean(L, extended ? 1 : 0); });
652 return 0; 652 return 0;
653} 653}
654 654
@@ -659,16 +659,16 @@ LUAG_FUNC( set_error_reporting)
659 659
660 // Don't do stack survey for cancelled lanes. 660 // Don't do stack survey for cancelled lanes.
661 // 661 //
662 if (CANCEL_ERROR.equals(L, 1)) 662 if (kCancelError.equals(L, 1))
663 { 663 {
664 return 1; // just pass on 664 return 1; // just pass on
665 } 665 }
666 666
667 STACK_GROW(L, 3); 667 STACK_GROW(L, 3);
668 bool const extended{ EXTENDED_STACKTRACE_REGKEY.readBoolValue(L) }; 668 bool const extended{ kExtendedStackTraceRegKey.readBoolValue(L) };
669 STACK_CHECK(L, 1); 669 STACK_CHECK(L, 1);
670 670
671 // Place stack trace at 'registry[STACKTRACE_REGKEY]' for the 'lua_pcall()' 671 // Place stack trace at 'registry[kStackTraceRegKey]' for the 'lua_pcall()'
672 // caller to fetch. This bypasses the Lua 5.1 limitation of only one 672 // caller to fetch. This bypasses the Lua 5.1 limitation of only one
673 // return value from error handler to 'lua_pcall()' caller. 673 // return value from error handler to 'lua_pcall()' caller.
674 674
@@ -719,7 +719,7 @@ LUAG_FUNC( set_error_reporting)
719 } 719 }
720 720
721 // store the stack trace table in the registry 721 // store the stack trace table in the registry
722 STACKTRACE_REGKEY.setValue(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error 722 kStackTraceRegKey.setValue(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error
723 723
724 STACK_CHECK(L, 1); 724 STACK_CHECK(L, 1);
725 return 1; // the untouched error value 725 return 1; // the untouched error value
@@ -767,9 +767,9 @@ LUAG_FUNC(set_thread_priority)
767 // public Lanes API accepts a generic range -3/+3 767 // public Lanes API accepts a generic range -3/+3
768 // that will be remapped into the platform-specific scheduler priority scheme 768 // that will be remapped into the platform-specific scheduler priority scheme
769 // On some platforms, -3 is equivalent to -2 and +3 to +2 769 // On some platforms, -3 is equivalent to -2 and +3 to +2
770 if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) 770 if (prio < kThreadPrioMin || prio > kThreadPrioMax)
771 { 771 {
772 return luaL_error(L, "priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio); 772 return luaL_error(L, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio);
773 } 773 }
774 THREAD_SET_PRIORITY(static_cast<int>(prio), universe_get(L)->m_sudo); 774 THREAD_SET_PRIORITY(static_cast<int>(prio), universe_get(L)->m_sudo);
775 return 0; 775 return 0;
@@ -870,7 +870,7 @@ static void lane_main(Lane* lane)
870 // in case of error and if it exists, fetch stack trace from registry and push it 870 // in case of error and if it exists, fetch stack trace from registry and push it
871 push_stack_trace(L, rc, 1); // retvals|error [trace] 871 push_stack_trace(L, rc, 1); // retvals|error [trace]
872 872
873 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p body: %s (%s)\n" INDENT_END, L, get_errcode_name(rc), CANCEL_ERROR.equals(L, 1) ? "cancelled" : lua_typename(L, lua_type(L, 1)))); 873 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p body: %s (%s)\n" INDENT_END, L, get_errcode_name(rc), kCancelError.equals(L, 1) ? "cancelled" : lua_typename(L, lua_type(L, 1))));
874 // Call finalizers, if the script has set them up. 874 // Call finalizers, if the script has set them up.
875 // 875 //
876 int rc2{ run_finalizers(L, rc) }; 876 int rc2{ run_finalizers(L, rc) };
@@ -901,7 +901,7 @@ static void lane_main(Lane* lane)
901 { 901 {
902 // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them 902 // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them
903 903
904 Lane::Status st = (rc == LUA_OK) ? Lane::Done : CANCEL_ERROR.equals(L, 1) ? Lane::Cancelled : Lane::Error; 904 Lane::Status st = (rc == LUA_OK) ? Lane::Done : kCancelError.equals(L, 1) ? Lane::Cancelled : Lane::Error;
905 905
906 { 906 {
907 // 'm_done_mutex' protects the -> Done|Error|Cancelled state change 907 // 'm_done_mutex' protects the -> Done|Error|Cancelled state change
@@ -959,8 +959,8 @@ LUAG_FUNC(register)
959 959
960// ################################################################################################# 960// #################################################################################################
961 961
962// crc64/we of string "GCCB_KEY" generated at http://www.nitrxgen.net/hashgen/ 962// xxh64 of string "kLaneGC" generated at https://www.pelock.com/products/hash-calculator
963static constexpr UniqueKey GCCB_KEY{ 0xCFB1F046EF074E88ull }; 963static constexpr UniqueKey kLaneGC{ 0x5D6122141727F960ull };
964 964
965//--- 965//---
966// lane_ud = lane_new( function 966// lane_ud = lane_new( function
@@ -978,23 +978,23 @@ LUAG_FUNC(lane_new)
978{ 978{
979 char const* const libs_str{ lua_tostring(L, 2) }; 979 char const* const libs_str{ lua_tostring(L, 2) };
980 bool const have_priority{ !lua_isnoneornil(L, 3) }; 980 bool const have_priority{ !lua_isnoneornil(L, 3) };
981 int const priority{ have_priority ? (int) lua_tointeger(L, 3) : THREAD_PRIO_DEFAULT }; 981 int const priority{ have_priority ? (int) lua_tointeger(L, 3) : kThreadPrioDefault };
982 int const globals_idx{ lua_isnoneornil(L, 4) ? 0 : 4 }; 982 int const globals_idx{ lua_isnoneornil(L, 4) ? 0 : 4 };
983 int const package_idx{ lua_isnoneornil(L, 5) ? 0 : 5 }; 983 int const package_idx{ lua_isnoneornil(L, 5) ? 0 : 5 };
984 int const required_idx{ lua_isnoneornil(L, 6) ? 0 : 6 }; 984 int const required_idx{ lua_isnoneornil(L, 6) ? 0 : 6 };
985 int const gc_cb_idx{ lua_isnoneornil(L, 7) ? 0 : 7 }; 985 int const gc_cb_idx{ lua_isnoneornil(L, 7) ? 0 : 7 };
986 986
987 static constexpr int FIXED_ARGS{ 7 }; 987 static constexpr int kFixedArgsIdx{ 7 };
988 int const nargs{ lua_gettop(L) - FIXED_ARGS }; 988 int const nargs{ lua_gettop(L) - kFixedArgsIdx };
989 Universe* const U{ universe_get(L) }; 989 Universe* const U{ universe_get(L) };
990 LUA_ASSERT(L, nargs >= 0); 990 LUA_ASSERT(L, nargs >= 0);
991 991
992 // public Lanes API accepts a generic range -3/+3 992 // public Lanes API accepts a generic range -3/+3
993 // that will be remapped into the platform-specific scheduler priority scheme 993 // that will be remapped into the platform-specific scheduler priority scheme
994 // On some platforms, -3 is equivalent to -2 and +3 to +2 994 // On some platforms, -3 is equivalent to -2 and +3 to +2
995 if (have_priority && (priority < THREAD_PRIO_MIN || priority > THREAD_PRIO_MAX)) 995 if (have_priority && (priority < kThreadPrioMin || priority > kThreadPrioMax))
996 { 996 {
997 return luaL_error(L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, priority); 997 return luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority);
998 } 998 }
999 999
1000 /* --- Create and prepare the sub state --- */ 1000 /* --- Create and prepare the sub state --- */
@@ -1039,7 +1039,7 @@ LUAG_FUNC(lane_new)
1039 prepareUserData(); 1039 prepareUserData();
1040 // leave a single cancel_error on the stack for the caller 1040 // leave a single cancel_error on the stack for the caller
1041 lua_settop(m_lane->L, 0); 1041 lua_settop(m_lane->L, 0);
1042 CANCEL_ERROR.pushKey(m_lane->L); 1042 kCancelError.pushKey(m_lane->L);
1043 { 1043 {
1044 std::lock_guard lock{ m_lane->m_done_mutex }; 1044 std::lock_guard lock{ m_lane->m_done_mutex };
1045 m_lane->m_status = Lane::Cancelled; 1045 m_lane->m_status = Lane::Cancelled;
@@ -1073,7 +1073,7 @@ LUAG_FUNC(lane_new)
1073 // Store the gc_cb callback in the uservalue 1073 // Store the gc_cb callback in the uservalue
1074 if (m_gc_cb_idx > 0) 1074 if (m_gc_cb_idx > 0)
1075 { 1075 {
1076 GCCB_KEY.pushKey(m_L); // ... lane uv k 1076 kLaneGC.pushKey(m_L); // ... lane uv k
1077 lua_pushvalue(m_L, m_gc_cb_idx); // ... lane uv k gc_cb 1077 lua_pushvalue(m_L, m_gc_cb_idx); // ... lane uv k gc_cb
1078 lua_rawset(m_L, -3); // ... lane uv 1078 lua_rawset(m_L, -3); // ... lane uv
1079 } 1079 }
@@ -1243,10 +1243,10 @@ LUAG_FUNC(lane_new)
1243 } 1243 }
1244 } 1244 }
1245 STACK_CHECK(L, -nargs); 1245 STACK_CHECK(L, -nargs);
1246 LUA_ASSERT(L, lua_gettop( L) == FIXED_ARGS); 1246 LUA_ASSERT(L, lua_gettop(L) == kFixedArgsIdx);
1247 1247
1248 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). 1248 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
1249 LANE_POINTER_REGKEY.setValue(L2, [lane](lua_State* L) { lua_pushlightuserdata(L, lane); }); // func [... args ...] 1249 kLanePointerRegKey.setValue(L2, [lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); }); // func [... args ...]
1250 STACK_CHECK(L2, 1 + nargs); 1250 STACK_CHECK(L2, 1 + nargs);
1251 1251
1252 STACK_CHECK_RESET_REL(L, 0); 1252 STACK_CHECK_RESET_REL(L, 0);
@@ -1278,7 +1278,7 @@ LUAG_FUNC(lane_new)
1278 1278
1279 // if there a gc callback? 1279 // if there a gc callback?
1280 lua_getiuservalue(L, 1, 1); // ud uservalue 1280 lua_getiuservalue(L, 1, 1); // ud uservalue
1281 GCCB_KEY.pushKey(L); // ud uservalue __gc 1281 kLaneGC.pushKey(L); // ud uservalue __gc
1282 lua_rawget(L, -2); // ud uservalue gc_cb|nil 1282 lua_rawget(L, -2); // ud uservalue gc_cb|nil
1283 if (!lua_isnil(L, -1)) 1283 if (!lua_isnil(L, -1))
1284 { 1284 {
@@ -1441,9 +1441,9 @@ LUAG_FUNC(thread_join)
1441 return ret; 1441 return ret;
1442} 1442}
1443 1443
1444// #################################################################################################
1444 1445
1445//--- 1446// lane:__index(key,usr) -> value
1446// thread_index( ud, key) -> value
1447// 1447//
1448// If key is found in the environment, return it 1448// If key is found in the environment, return it
1449// If key is numeric, wait until the thread returns and populate the environment with the return values 1449// If key is numeric, wait until the thread returns and populate the environment with the return values
@@ -1452,44 +1452,43 @@ LUAG_FUNC(thread_join)
1452// Else raise an error 1452// Else raise an error
1453LUAG_FUNC(thread_index) 1453LUAG_FUNC(thread_index)
1454{ 1454{
1455 static constexpr int UD{ 1 }; 1455 static constexpr int kSelf{ 1 };
1456 static constexpr int KEY{ 2 }; 1456 static constexpr int kKey{ 2 };
1457 static constexpr int USR{ 3 }; 1457 Lane* const lane{ ToLane(L, kSelf) };
1458 Lane* const lane{ ToLane(L, UD) };
1459 LUA_ASSERT(L, lua_gettop(L) == 2); 1458 LUA_ASSERT(L, lua_gettop(L) == 2);
1460 1459
1461 STACK_GROW(L, 8); // up to 8 positions are needed in case of error propagation 1460 STACK_GROW(L, 8); // up to 8 positions are needed in case of error propagation
1462 1461
1463 // If key is numeric, wait until the thread returns and populate the environment with the return values 1462 // If key is numeric, wait until the thread returns and populate the environment with the return values
1464 if (lua_type(L, KEY) == LUA_TNUMBER) 1463 if (lua_type(L, kKey) == LUA_TNUMBER)
1465 { 1464 {
1465 static constexpr int kUsr{ 3 };
1466 // first, check that we don't already have an environment that holds the requested value 1466 // first, check that we don't already have an environment that holds the requested value
1467 { 1467 {
1468 // If key is found in the uservalue, return it 1468 // If key is found in the uservalue, return it
1469 lua_getiuservalue(L, UD, 1); 1469 lua_getiuservalue(L, kSelf, 1);
1470 lua_pushvalue(L, KEY); 1470 lua_pushvalue(L, kKey);
1471 lua_rawget(L, USR); 1471 lua_rawget(L, kUsr);
1472 if (!lua_isnil(L, -1)) 1472 if (!lua_isnil(L, -1))
1473 { 1473 {
1474 return 1; 1474 return 1;
1475 } 1475 }
1476 lua_pop(L, 1); 1476 lua_pop(L, 1);
1477 } 1477 }
1478 { 1478 {
1479 // check if we already fetched the values from the thread or not 1479 // check if we already fetched the values from the thread or not
1480 lua_Integer key = lua_tointeger(L, KEY);
1481 lua_pushinteger(L, 0); 1480 lua_pushinteger(L, 0);
1482 lua_rawget(L, USR); 1481 lua_rawget(L, kUsr);
1483 bool const fetched{ !lua_isnil(L, -1) }; 1482 bool const fetched{ !lua_isnil(L, -1) };
1484 lua_pop(L, 1); // back to our 2 args + uservalue on the stack 1483 lua_pop(L, 1); // back to our 2 args + uservalue on the stack
1485 if (!fetched) 1484 if (!fetched)
1486 { 1485 {
1487 lua_pushinteger(L, 0); 1486 lua_pushinteger(L, 0);
1488 lua_pushboolean(L, 1); 1487 lua_pushboolean(L, 1);
1489 lua_rawset(L, USR); 1488 lua_rawset(L, kUsr);
1490 // wait until thread has completed 1489 // wait until thread has completed
1491 lua_pushcfunction(L, LG_thread_join); 1490 lua_pushcfunction(L, LG_thread_join);
1492 lua_pushvalue(L, UD); 1491 lua_pushvalue(L, kSelf);
1493 lua_call(L, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ 1492 lua_call(L, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+
1494 switch (lane->m_status) 1493 switch (lane->m_status)
1495 { 1494 {
@@ -1508,7 +1507,7 @@ LUAG_FUNC(thread_index)
1508 for (int i = nvalues; i > 0; --i) 1507 for (int i = nvalues; i > 0; --i)
1509 { 1508 {
1510 // pop the last element of the stack, to store it in the uservalue at its proper index 1509 // pop the last element of the stack, to store it in the uservalue at its proper index
1511 lua_rawseti(L, USR, i); 1510 lua_rawseti(L, kUsr, i);
1512 } 1511 }
1513 } 1512 }
1514 break; 1513 break;
@@ -1521,7 +1520,7 @@ LUAG_FUNC(thread_index)
1521 // store errstring at key -1 1520 // store errstring at key -1
1522 lua_pushnumber(L, -1); 1521 lua_pushnumber(L, -1);
1523 lua_pushvalue(L, 5); 1522 lua_pushvalue(L, 5);
1524 lua_rawset(L, USR); 1523 lua_rawset(L, kUsr);
1525 break; 1524 break;
1526 1525
1527 case Lane::Cancelled: 1526 case Lane::Cancelled:
@@ -1529,11 +1528,12 @@ LUAG_FUNC(thread_index)
1529 break; 1528 break;
1530 } 1529 }
1531 } 1530 }
1532 lua_settop(L, 3); // UD KEY ENV 1531 lua_settop(L, 3); // self KEY ENV
1532 int const key{ static_cast<int>(lua_tointeger(L, kKey)) };
1533 if (key != -1) 1533 if (key != -1)
1534 { 1534 {
1535 lua_pushnumber(L, -1); // UD KEY ENV -1 1535 lua_pushnumber(L, -1); // self KEY ENV -1
1536 lua_rawget(L, USR); // UD KEY ENV "error" 1536 lua_rawget(L, kUsr); // self KEY ENV "error"|nil
1537 if (!lua_isnil(L, -1)) // an error was stored 1537 if (!lua_isnil(L, -1)) // an error was stored
1538 { 1538 {
1539 // Note: Lua 5.1 interpreter is not prepared to show 1539 // Note: Lua 5.1 interpreter is not prepared to show
@@ -1547,48 +1547,48 @@ LUAG_FUNC(thread_index)
1547 // Level 3 should show the line where 'h[x]' was read 1547 // Level 3 should show the line where 'h[x]' was read
1548 // but this only seems to work for string messages 1548 // but this only seems to work for string messages
1549 // (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009 1549 // (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009
1550 lua_getmetatable(L, UD); // UD KEY ENV "error" mt 1550 lua_getmetatable(L, kSelf); // self KEY ENV "error" mt
1551 lua_getfield(L, -1, "cached_error"); // UD KEY ENV "error" mt error() 1551 lua_getfield(L, -1, "cached_error"); // self KEY ENV "error" mt error()
1552 lua_getfield(L, -2, "cached_tostring"); // UD KEY ENV "error" mt error() tostring() 1552 lua_getfield(L, -2, "cached_tostring"); // self KEY ENV "error" mt error() tostring()
1553 lua_pushvalue(L, 4); // UD KEY ENV "error" mt error() tostring() "error" 1553 lua_pushvalue(L, 4); // self KEY ENV "error" mt error() tostring() "error"
1554 lua_call(L, 1, 1); // tostring( errstring) -- just in case // UD KEY ENV "error" mt error() "error" 1554 lua_call(L, 1, 1); // tostring( errstring) -- just in case // self KEY ENV "error" mt error() "error"
1555 lua_pushinteger(L, 3); // UD KEY ENV "error" mt error() "error" 3 1555 lua_pushinteger(L, 3); // self KEY ENV "error" mt error() "error" 3
1556 lua_call(L, 2, 0); // error( tostring( errstring), 3) // UD KEY ENV "error" mt 1556 lua_call(L, 2, 0); // error( tostring( errstring), 3) // self KEY ENV "error" mt
1557 } 1557 }
1558 else 1558 else
1559 { 1559 {
1560 lua_pop(L, 1); // back to our 3 arguments on the stack 1560 lua_pop(L, 1); // self KEY ENV
1561 } 1561 }
1562 } 1562 }
1563 lua_rawgeti(L, USR, (int)key); 1563 lua_rawgeti(L, kUsr, key);
1564 } 1564 }
1565 return 1; 1565 return 1;
1566 } 1566 }
1567 if (lua_type(L, KEY) == LUA_TSTRING) 1567 if (lua_type(L, kKey) == LUA_TSTRING)
1568 { 1568 {
1569 char const* const keystr{ lua_tostring(L, KEY) }; 1569 char const* const keystr{ lua_tostring(L, kKey) };
1570 lua_settop(L, 2); // keep only our original arguments on the stack 1570 lua_settop(L, 2); // keep only our original arguments on the stack
1571 if (strcmp( keystr, "status") == 0) 1571 if (strcmp( keystr, "status") == 0)
1572 { 1572 {
1573 lane->pushThreadStatus(L); // push the string representing the status 1573 lane->pushThreadStatus(L); // push the string representing the status
1574 return 1; 1574 return 1;
1575 } 1575 }
1576 // return UD.metatable[key] 1576 // return self.metatable[key]
1577 lua_getmetatable(L, UD); // UD KEY mt 1577 lua_getmetatable(L, kSelf); // self KEY mt
1578 lua_replace(L, -3); // mt KEY 1578 lua_replace(L, -3); // mt KEY
1579 lua_rawget(L, -2); // mt value 1579 lua_rawget(L, -2); // mt value
1580 // only "cancel" and "join" are registered as functions, any other string will raise an error 1580 // only "cancel" and "join" are registered as functions, any other string will raise an error
1581 if (lua_iscfunction(L, -1)) 1581 if (!lua_iscfunction(L, -1))
1582 { 1582 {
1583 return 1; 1583 luaL_error(L, "can't index a lane with '%s'", keystr); // doesn't return
1584 } 1584 }
1585 return luaL_error(L, "can't index a lane with '%s'", keystr); 1585 return 1;
1586 } 1586 }
1587 // unknown key 1587 // unknown key
1588 lua_getmetatable(L, UD); 1588 lua_getmetatable(L, kSelf);
1589 lua_getfield(L, -1, "cached_error"); 1589 lua_getfield(L, -1, "cached_error");
1590 lua_pushliteral(L, "Unknown key: "); 1590 lua_pushliteral(L, "Unknown key: ");
1591 lua_pushvalue(L, KEY); 1591 lua_pushvalue(L, kKey);
1592 lua_concat(L, 2); 1592 lua_concat(L, 2);
1593 lua_call(L, 1, 0); // error( "Unknown key: " .. key) -> doesn't return 1593 lua_call(L, 1, 0); // error( "Unknown key: " .. key) -> doesn't return
1594 return 0; 1594 return 0;
@@ -1863,15 +1863,19 @@ LUAG_FUNC(configure)
1863 ); // settings M VERSION 1863 ); // settings M VERSION
1864 lua_setfield(L, -2, "version"); // settings M 1864 lua_setfield(L, -2, "version"); // settings M
1865 1865
1866 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX 1866 lua_pushinteger(L, kThreadPrioMax); // settings M kThreadPrioMax
1867 lua_setfield(L, -2, "max_prio"); // settings M 1867 lua_setfield(L, -2, "max_prio"); // settings M
1868 1868
1869 CANCEL_ERROR.pushKey(L); // settings M CANCEL_ERROR 1869 kCancelError.pushKey(L); // settings M kCancelError
1870 lua_setfield(L, -2, "cancel_error"); // settings M 1870 lua_setfield(L, -2, "cancel_error"); // settings M
1871 1871
1872 /* to activate in a separate commit
1873 kNilSentinel.pushKey(L); // settings M kNilSentinel
1874 lua_setfield(L, -2, "null"); // settings M
1875 */
1872 STACK_CHECK(L, 2); // reference stack contains only the function argument 'settings' 1876 STACK_CHECK(L, 2); // reference stack contains only the function argument 'settings'
1873 // we'll need this every time we transfer some C function from/to this state 1877 // we'll need this every time we transfer some C function from/to this state
1874 LOOKUP_REGKEY.setValue(L, [](lua_State* L) { lua_newtable(L); }); // settings M 1878 kLookupRegKey.setValue(L, [](lua_State* L) { lua_newtable(L); }); // settings M
1875 STACK_CHECK(L, 2); 1879 STACK_CHECK(L, 2);
1876 1880
1877 // register all native functions found in that module in the transferable functions database 1881 // register all native functions found in that module in the transferable functions database
@@ -1893,8 +1897,8 @@ LUAG_FUNC(configure)
1893 } 1897 }
1894 lua_pop(L, 1); // settings 1898 lua_pop(L, 1); // settings
1895 1899
1896 // set _R[CONFIG_REGKEY] = settings 1900 // set _R[kConfigRegKey] = settings
1897 CONFIG_REGKEY.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 1901 kConfigRegKey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); });
1898 STACK_CHECK(L, 1); 1902 STACK_CHECK(L, 1);
1899 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); 1903 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L));
1900 // Return the settings table 1904 // Return the settings table
@@ -1986,7 +1990,7 @@ LANES_API int luaopen_lanes_core( lua_State* L)
1986 lua_pushvalue(L, 1); // M "lanes.core" 1990 lua_pushvalue(L, 1); // M "lanes.core"
1987 lua_pushvalue(L, -2); // M "lanes.core" M 1991 lua_pushvalue(L, -2); // M "lanes.core" M
1988 lua_pushcclosure(L, LG_configure, 2); // M LG_configure() 1992 lua_pushcclosure(L, LG_configure, 2); // M LG_configure()
1989 CONFIG_REGKEY.pushValue(L); // M LG_configure() settings 1993 kConfigRegKey.pushValue(L); // M LG_configure() settings
1990 if (!lua_isnil(L, -1)) // this is not the first require "lanes.core": call configure() immediately 1994 if (!lua_isnil(L, -1)) // this is not the first require "lanes.core": call configure() immediately
1991 { 1995 {
1992 lua_pushvalue(L, -1); // M LG_configure() settings settings 1996 lua_pushvalue(L, -1); // M LG_configure() settings settings