aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp126
1 files changed, 75 insertions, 51 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index d1a353b..4373aee 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -137,13 +137,15 @@ LUAG_FUNC(set_singlethreaded)
137LUAG_FUNC(set_thread_priority) 137LUAG_FUNC(set_thread_priority)
138{ 138{
139 lua_Integer const _prio{ luaL_checkinteger(L_, 1) }; 139 lua_Integer const _prio{ luaL_checkinteger(L_, 1) };
140 NativePrioFlag const _native{ std::string_view{ "native" } == luaL_optstring(L_, 2, "mapped") };
140 // public Lanes API accepts a generic range -3/+3 141 // public Lanes API accepts a generic range -3/+3
141 // that will be remapped into the platform-specific scheduler priority scheme 142 // that will be remapped into the platform-specific scheduler priority scheme
142 // On some platforms, -3 is equivalent to -2 and +3 to +2 143 // On some platforms, -3 is equivalent to -2 and +3 to +2
143 if (_prio < kThreadPrioMin || _prio > kThreadPrioMax) { 144 if (!_native && (_prio < kThreadPrioMin || _prio > kThreadPrioMax)) {
144 raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _prio); 145 raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _prio);
145 } 146 }
146 THREAD_SET_PRIORITY(static_cast<int>(_prio), Universe::Get(L_)->sudo); 147
148 THREAD_SET_PRIORITY(L_, static_cast<int>(_prio), _native, Universe::Get(L_)->sudo);
147 return 0; 149 return 0;
148} 150}
149 151
@@ -155,7 +157,8 @@ LUAG_FUNC(set_thread_affinity)
155 if (_affinity <= 0) { 157 if (_affinity <= 0) {
156 raise_luaL_error(L_, "invalid affinity (%d)", _affinity); 158 raise_luaL_error(L_, "invalid affinity (%d)", _affinity);
157 } 159 }
158 THREAD_SET_AFFINITY(static_cast<unsigned int>(_affinity)); 160
161 THREAD_SET_AFFINITY(L_, static_cast<unsigned int>(_affinity));
159 return 0; 162 return 0;
160} 163}
161 164
@@ -170,17 +173,21 @@ LUAG_FUNC(sleep)
170 lua_pushcfunction(L_, LG_linda_receive); // L_: duration|nil receive() 173 lua_pushcfunction(L_, LG_linda_receive); // L_: duration|nil receive()
171 STACK_CHECK_START_REL(L_, 0); // we pushed the function we intend to call, now prepare the arguments 174 STACK_CHECK_START_REL(L_, 0); // we pushed the function we intend to call, now prepare the arguments
172 _U->timerLinda->push(L_); // L_: duration|nil receive() timerLinda 175 _U->timerLinda->push(L_); // L_: duration|nil receive() timerLinda
173 if (luaG_tostring(L_, StackIndex{ 1 }) == "indefinitely") { 176 if (luaW_tostring(L_, StackIndex{ 1 }) == "indefinitely") {
174 lua_pushnil(L_); // L_: duration? receive() timerLinda nil 177 lua_pushnil(L_); // L_: duration? receive() timerLinda nil
175 } else if (lua_isnoneornil(L_, 1)) { 178 } else if (lua_isnoneornil(L_, 1)) {
176 lua_pushnumber(L_, 0); // L_: duration? receive() timerLinda 0 179 lua_pushnumber(L_, 0); // L_: duration? receive() timerLinda 0
177 } else if (!lua_isnumber(L_, 1)) { 180 } else if (!lua_isnumber(L_, 1)) {
178 raise_luaL_argerror(L_, StackIndex{ 1 }, "invalid duration"); 181 raise_luaL_argerror(L_, StackIndex{ 1 }, "duration must be a number");
179 } 182 }
180 else { 183 else {
184 auto const _n{ lua_tonumber(L_, 1) };
185 if (_n < 0) {
186 raise_luaL_argerror(L_, StackIndex{ 1 }, "duration must be >= 0");
187 }
181 lua_pushnumber(L_, lua_tonumber(L_, 1)); // L_: duration? receive() timerLinda duration 188 lua_pushnumber(L_, lua_tonumber(L_, 1)); // L_: duration? receive() timerLinda duration
182 } 189 }
183 luaG_pushstring(L_, "ac100de1-a696-4619-b2f0-a26de9d58ab8"); // L_: duration? receive() timerLinda duration key 190 luaW_pushstring(L_, "ac100de1-a696-4619-b2f0-a26de9d58ab8"); // L_: duration? receive() timerLinda duration key
184 STACK_CHECK(L_, 3); // 3 arguments ready 191 STACK_CHECK(L_, 3); // 3 arguments ready
185 lua_call(L_, 3, LUA_MULTRET); // timerLinda:receive(duration,key) // L_: duration? result... 192 lua_call(L_, 3, LUA_MULTRET); // timerLinda:receive(duration,key) // L_: duration? result...
186 return lua_gettop(L_) - 1; 193 return lua_gettop(L_) - 1;
@@ -194,7 +201,7 @@ LUAG_FUNC(sleep)
194// upvalue[1]: _G.require 201// upvalue[1]: _G.require
195LUAG_FUNC(require) 202LUAG_FUNC(require)
196{ 203{
197 std::string_view const _name{ luaG_tostring(L_, StackIndex{ 1 }) }; // L_: "name" ... 204 std::string_view const _name{ luaW_tostring(L_, StackIndex{ 1 }) }; // L_: "name" ...
198 int const _nargs{ lua_gettop(L_) }; 205 int const _nargs{ lua_gettop(L_) };
199 DEBUGSPEW_CODE(Universe * _U{ Universe::Get(L_) }); 206 DEBUGSPEW_CODE(Universe * _U{ Universe::Get(L_) });
200 STACK_CHECK_START_REL(L_, 0); 207 STACK_CHECK_START_REL(L_, 0);
@@ -220,8 +227,8 @@ int lanes_register(lua_State* const L_)
220 if (!_U) { 227 if (!_U) {
221 raise_luaL_error(L_, "Lanes is not ready"); 228 raise_luaL_error(L_, "Lanes is not ready");
222 } 229 }
223 std::string_view const _name{ luaG_checkstring(L_, StackIndex{ 1 }) }; 230 std::string_view const _name{ luaW_checkstring(L_, StackIndex{ 1 }) };
224 LuaType const _mod_type{ luaG_type(L_, StackIndex{ 2 }) }; 231 LuaType const _mod_type{ luaW_type(L_, StackIndex{ 2 }) };
225 // ignore extra arguments, just in case 232 // ignore extra arguments, just in case
226 lua_settop(L_, 2); 233 lua_settop(L_, 2);
227 luaL_argcheck(L_, (_mod_type == LuaType::TABLE) || (_mod_type == LuaType::FUNCTION), 2, "unexpected module type"); 234 luaL_argcheck(L_, (_mod_type == LuaType::TABLE) || (_mod_type == LuaType::FUNCTION), 2, "unexpected module type");
@@ -236,9 +243,26 @@ int lanes_register(lua_State* const L_)
236 243
237// ################################################################################################# 244// #################################################################################################
238 245
246LUAG_FUNC(thread_priority_range)
247{
248 NativePrioFlag const _native{ std::string_view{ "native" } == luaL_optstring(L_, 1, "mapped") };
249 if (_native) {
250 auto const [_prio_min, _prio_max] = THREAD_NATIVE_PRIOS();
251 lua_pushinteger(L_, _prio_min);
252 lua_pushinteger(L_, _prio_max);
253 } else {
254 lua_pushinteger(L_, kThreadPrioMin);
255 lua_pushinteger(L_, kThreadPrioMax);
256 }
257 return 2;
258}
259
260// #################################################################################################
261
239//--- [] means can be nil 262//--- [] means can be nil
240// lane_ud = lane_new( function 263// lane_ud = lane_new( function
241// , [libs_str] 264// , [libs_str]
265// , [prio_is_native_bool]
242// , [priority_int] 266// , [priority_int]
243// , [globals_tbl] 267// , [globals_tbl]
244// , [package_tbl] 268// , [package_tbl]
@@ -255,15 +279,16 @@ LUAG_FUNC(lane_new)
255{ 279{
256 static constexpr StackIndex kFuncIdx{ 1 }; 280 static constexpr StackIndex kFuncIdx{ 1 };
257 static constexpr StackIndex kLibsIdx{ 2 }; 281 static constexpr StackIndex kLibsIdx{ 2 };
258 static constexpr StackIndex kPrioIdx{ 3 }; 282 static constexpr StackIndex kPrinIdx{ 3 };
259 static constexpr StackIndex kGlobIdx{ 4 }; 283 static constexpr StackIndex kPrioIdx{ 4 };
260 static constexpr StackIndex kPackIdx{ 5 }; 284 static constexpr StackIndex kGlobIdx{ 5 };
261 static constexpr StackIndex kRequIdx{ 6 }; 285 static constexpr StackIndex kPackIdx{ 6 };
262 static constexpr StackIndex kGcCbIdx{ 7 }; 286 static constexpr StackIndex kRequIdx{ 7 };
263 static constexpr StackIndex kNameIdx{ 8 }; 287 static constexpr StackIndex kGcCbIdx{ 8 };
264 static constexpr StackIndex kErTlIdx{ 9 }; 288 static constexpr StackIndex kNameIdx{ 9 };
265 static constexpr StackIndex kAsCoro{ 10 }; 289 static constexpr StackIndex kErTlIdx{ 10 };
266 static constexpr StackIndex kFixedArgsIdx{ 10 }; 290 static constexpr StackIndex kAsCoro{ 11 };
291 static constexpr StackIndex kFixedArgsIdx{ 11 };
267 292
268 int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; 293 int const _nargs{ lua_gettop(L_) - kFixedArgsIdx };
269 LUA_ASSERT(L_, _nargs >= 0); 294 LUA_ASSERT(L_, _nargs >= 0);
@@ -271,7 +296,7 @@ LUAG_FUNC(lane_new)
271 Universe* const _U{ Universe::Get(L_) }; 296 Universe* const _U{ Universe::Get(L_) };
272 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); 297 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl);
273 298
274 std::optional<std::string_view> _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(luaG_tostring(L_, kLibsIdx)) }; 299 std::optional<std::string_view> _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(luaW_tostring(L_, kLibsIdx)) };
275 lua_State* const _S{ state::NewLaneState(_U, SourceState{ L_ }, _libs_str) }; // L_: [fixed] ... L2: 300 lua_State* const _S{ state::NewLaneState(_U, SourceState{ L_ }, _libs_str) }; // L_: [fixed] ... L2:
276 STACK_CHECK_START_REL(_S, 0); 301 STACK_CHECK_START_REL(_S, 0);
277 302
@@ -333,7 +358,7 @@ LUAG_FUNC(lane_new)
333 DEBUGSPEW_CODE(DebugSpew(lane->U) << "lane_new: preparing lane userdata" << std::endl); 358 DEBUGSPEW_CODE(DebugSpew(lane->U) << "lane_new: preparing lane userdata" << std::endl);
334 STACK_CHECK_START_REL(L, 0); 359 STACK_CHECK_START_REL(L, 0);
335 // a Lane full userdata needs a single uservalue 360 // a Lane full userdata needs a single uservalue
336 Lane** const _ud{ luaG_newuserdatauv<Lane*>(L, UserValueCount{ 1 }) }; // L: ... lane 361 Lane** const _ud{ luaW_newuserdatauv<Lane*>(L, UserValueCount{ 1 }) }; // L: ... lane
337 *_ud = lane; // don't forget to store the pointer in the userdata! 362 *_ud = lane; // don't forget to store the pointer in the userdata!
338 363
339 // Set metatable for the userdata 364 // Set metatable for the userdata
@@ -357,25 +382,25 @@ LUAG_FUNC(lane_new)
357 lua_setiuservalue(L, StackIndex{ -2 }, UserValueIndex{ 1 }); // L: ... lane 382 lua_setiuservalue(L, StackIndex{ -2 }, UserValueIndex{ 1 }); // L: ... lane
358 383
359 StackIndex const _name_idx{ lua_isnoneornil(L, kNameIdx) ? kIdxNone : kNameIdx }; 384 StackIndex const _name_idx{ lua_isnoneornil(L, kNameIdx) ? kIdxNone : kNameIdx };
360 std::string_view _debugName{ (_name_idx > 0) ? luaG_tostring(L, _name_idx) : std::string_view{} }; 385 std::string_view _debugName{ (_name_idx > 0) ? luaW_tostring(L, _name_idx) : std::string_view{} };
361 if (!_debugName.empty()) 386 if (!_debugName.empty())
362 { 387 {
363 if (_debugName == "auto") { 388 if (_debugName == "auto") {
364 if (luaG_type(L, kFuncIdx) == LuaType::STRING) { 389 if (luaW_type(L, kFuncIdx) == LuaType::STRING) {
365 lua_Debug _ar; 390 lua_Debug _ar;
366 if (lua_getstack(L, 2, &_ar) == 0) { // 0 is here, 1 is lanes.gen, 2 is its caller 391 if (lua_getstack(L, 2, &_ar) == 0) { // 0 is here, 1 is lanes.gen, 2 is its caller
367 lua_getstack(L, 1, &_ar); // level 2 may not exist with LuaJIT, try again with level 1 392 lua_getstack(L, 1, &_ar); // level 2 may not exist with LuaJIT, try again with level 1
368 } 393 }
369 lua_getinfo(L, "Sl", &_ar); 394 lua_getinfo(L, "Sl", &_ar);
370 luaG_pushstring(L, "%s:%d", _ar.short_src, _ar.currentline); // L: ... lane "<name>" 395 luaW_pushstring(L, "%s:%d", _ar.short_src, _ar.currentline); // L: ... lane "<name>"
371 } else { 396 } else {
372 lua_Debug _ar; 397 lua_Debug _ar;
373 lua_pushvalue(L, kFuncIdx); // L: ... lane func 398 lua_pushvalue(L, kFuncIdx); // L: ... lane func
374 lua_getinfo(L, ">S", &_ar); // L: ... lane 399 lua_getinfo(L, ">S", &_ar); // L: ... lane
375 luaG_pushstring(L, "%s:%d", _ar.short_src, _ar.linedefined); // L: ... lane "<name>" 400 luaW_pushstring(L, "%s:%d", _ar.short_src, _ar.linedefined); // L: ... lane "<name>"
376 } 401 }
377 lua_replace(L, _name_idx); // L: ... lane 402 lua_replace(L, _name_idx); // L: ... lane
378 _debugName = luaG_tostring(L, _name_idx); 403 _debugName = luaW_tostring(L, _name_idx);
379 } 404 }
380 lane->storeDebugName(_debugName); 405 lane->storeDebugName(_debugName);
381 } 406 }
@@ -400,21 +425,22 @@ LUAG_FUNC(lane_new)
400 // public Lanes API accepts a generic range -3/+3 425 // public Lanes API accepts a generic range -3/+3
401 // that will be remapped into the platform-specific scheduler priority scheme 426 // that will be remapped into the platform-specific scheduler priority scheme
402 // On some platforms, -3 is equivalent to -2 and +3 to +2 427 // On some platforms, -3 is equivalent to -2 and +3 to +2
403 int const _priority{ 428 auto const [_priority, _native] {
404 std::invoke([L = L_]() { 429 std::invoke([L = L_]() {
430 NativePrioFlag const _native{ static_cast<bool>(lua_toboolean(L, kPrinIdx)) };
405 StackIndex const _prio_idx{ lua_isnoneornil(L, kPrioIdx) ? kIdxNone : kPrioIdx }; 431 StackIndex const _prio_idx{ lua_isnoneornil(L, kPrioIdx) ? kIdxNone : kPrioIdx };
406 if (_prio_idx == 0) { 432 if (_prio_idx == kIdxNone) {
407 return kThreadPrioDefault; 433 return std::make_pair(kThreadPrioDefault, _native);
408 } 434 }
409 int const _priority{ static_cast<int>(lua_tointeger(L, _prio_idx)) }; 435 int const _priority{ static_cast<int>(lua_tointeger(L, _prio_idx)) };
410 if ((_priority < kThreadPrioMin || _priority > kThreadPrioMax)) { 436 if (!_native && (_priority < kThreadPrioMin || _priority > kThreadPrioMax)) {
411 raise_luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _priority); 437 raise_luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _priority);
412 } 438 }
413 return _priority; 439 return std::make_pair(_priority, _native);
414 }) 440 })
415 }; 441 };
416 442
417 _lane->startThread(_priority); 443 _lane->startThread(L_, _priority, _native);
418 444
419 STACK_GROW(_L2, _nargs + 3); 445 STACK_GROW(_L2, _nargs + 3);
420 STACK_GROW(L_, 3); 446 STACK_GROW(L_, 3);
@@ -439,17 +465,17 @@ LUAG_FUNC(lane_new)
439 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: process 'required' list" << std::endl); 465 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: process 'required' list" << std::endl);
440 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); 466 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U });
441 // should not happen, was checked in lanes.lua before calling lane_new() 467 // should not happen, was checked in lanes.lua before calling lane_new()
442 if (luaG_type(L_, _required_idx) != LuaType::TABLE) { 468 if (luaW_type(L_, _required_idx) != LuaType::TABLE) {
443 raise_luaL_error(L_, "expected required module list as a table, got %s", luaL_typename(L_, _required_idx)); 469 raise_luaL_error(L_, "expected required module list as a table, got %s", luaL_typename(L_, _required_idx));
444 } 470 }
445 471
446 lua_pushnil(L_); // L_: [fixed] args... nil L2: 472 lua_pushnil(L_); // L_: [fixed] args... nil L2:
447 while (lua_next(L_, _required_idx) != 0) { // L_: [fixed] args... n "modname" L2: 473 while (lua_next(L_, _required_idx) != 0) { // L_: [fixed] args... n "modname" L2:
448 if (luaG_type(L_, kIdxTop) != LuaType::STRING || luaG_type(L_, StackIndex{ -2 }) != LuaType::NUMBER || lua_tonumber(L_, -2) != _nbRequired) { 474 if (luaW_type(L_, kIdxTop) != LuaType::STRING || luaW_type(L_, StackIndex{ -2 }) != LuaType::NUMBER || lua_tonumber(L_, -2) != _nbRequired) {
449 raise_luaL_error(L_, "required module list should be a list of strings"); 475 raise_luaL_error(L_, "required module list should be a list of strings");
450 } else { 476 } else {
451 // require the module in the target state, and populate the lookup table there too 477 // require the module in the target state, and populate the lookup table there too
452 std::string_view const _name{ luaG_tostring(L_, kIdxTop) }; 478 std::string_view const _name{ luaW_tostring(L_, kIdxTop) };
453 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: require '" << _name << "'" << std::endl); 479 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: require '" << _name << "'" << std::endl);
454 480
455 // require the module in the target lane 481 // require the module in the target lane
@@ -458,7 +484,7 @@ LUAG_FUNC(lane_new)
458 lua_pop(_L2, 1); // L_: [fixed] args... n "modname" L2: 484 lua_pop(_L2, 1); // L_: [fixed] args... n "modname" L2:
459 raise_luaL_error(L_, "cannot pre-require modules without loading 'package' library first"); 485 raise_luaL_error(L_, "cannot pre-require modules without loading 'package' library first");
460 } else { 486 } else {
461 luaG_pushstring(_L2, _name); // L_: [fixed] args... n "modname" L2: require() name 487 luaW_pushstring(_L2, _name); // L_: [fixed] args... n "modname" L2: require() name
462 LuaError const _rc{ lua_pcall(_L2, 1, 1, 0) }; // L_: [fixed] args... n "modname" L2: ret/errcode 488 LuaError const _rc{ lua_pcall(_L2, 1, 1, 0) }; // L_: [fixed] args... n "modname" L2: ret/errcode
463 if (_rc != LuaError::OK) { 489 if (_rc != LuaError::OK) {
464 // propagate error to main state if any 490 // propagate error to main state if any
@@ -493,7 +519,7 @@ LUAG_FUNC(lane_new)
493 lua_pushnil(L_); // L_: [fixed] args... nil L2: 519 lua_pushnil(L_); // L_: [fixed] args... nil L2:
494 // Lua 5.2 wants us to push the globals table on the stack 520 // Lua 5.2 wants us to push the globals table on the stack
495 InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; 521 InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} };
496 luaG_pushglobaltable(_L2); // L_: [fixed] args... nil L2: _G 522 luaW_pushglobaltable(_L2); // L_: [fixed] args... nil L2: _G
497 while (lua_next(L_, _globals_idx)) { // L_: [fixed] args... k v L2: _G 523 while (lua_next(L_, _globals_idx)) { // L_: [fixed] args... k v L2: _G
498 std::ignore = _c.interCopy(2); // L_: [fixed] args... k v L2: _G k v 524 std::ignore = _c.interCopy(2); // L_: [fixed] args... k v L2: _G k v
499 // assign it in L2's globals table 525 // assign it in L2's globals table
@@ -507,7 +533,7 @@ LUAG_FUNC(lane_new)
507 533
508 // Lane main function 534 // Lane main function
509 [[maybe_unused]] int const _errorHandlerCount{ _lane->pushErrorHandler() }; // L_: [fixed] args... L2: eh? 535 [[maybe_unused]] int const _errorHandlerCount{ _lane->pushErrorHandler() }; // L_: [fixed] args... L2: eh?
510 LuaType const _func_type{ luaG_type(L_, kFuncIdx) }; 536 LuaType const _func_type{ luaW_type(L_, kFuncIdx) };
511 if (_func_type == LuaType::FUNCTION) { 537 if (_func_type == LuaType::FUNCTION) {
512 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: transfer lane body" << std::endl); 538 DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: transfer lane body" << std::endl);
513 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); 539 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U });
@@ -524,7 +550,7 @@ LUAG_FUNC(lane_new)
524 raise_luaL_error(L_, "error when parsing lane function code"); 550 raise_luaL_error(L_, "error when parsing lane function code");
525 } 551 }
526 } else { 552 } else {
527 raise_luaL_error(L_, "Expected function, got %s", luaG_typename(L_, _func_type).data()); 553 raise_luaL_error(L_, "Expected function, got %s", luaW_typename(L_, _func_type).data());
528 } 554 }
529 STACK_CHECK(L_, 0); 555 STACK_CHECK(L_, 0);
530 STACK_CHECK(_L2, _errorHandlerCount + 1); 556 STACK_CHECK(_L2, _errorHandlerCount + 1);
@@ -612,7 +638,7 @@ LUAG_FUNC(wakeup_conv)
612 638
613 STACK_CHECK_START_REL(L_, 0); 639 STACK_CHECK_START_REL(L_, 0);
614 auto _readInteger = [L = L_](std::string_view const& name_) { 640 auto _readInteger = [L = L_](std::string_view const& name_) {
615 std::ignore = luaG_getfield(L, StackIndex{ 1 }, name_); 641 std::ignore = luaW_getfield(L, StackIndex{ 1 }, name_);
616 lua_Integer const val{ lua_tointeger(L, -1) }; 642 lua_Integer const val{ lua_tointeger(L, -1) };
617 lua_pop(L, 1); 643 lua_pop(L, 1);
618 return static_cast<int>(val); 644 return static_cast<int>(val);
@@ -628,7 +654,7 @@ LUAG_FUNC(wakeup_conv)
628 // If Lua table has '.isdst' we trust that. If it does not, we'll let 654 // If Lua table has '.isdst' we trust that. If it does not, we'll let
629 // 'mktime' decide on whether the time is within DST or not (value -1). 655 // 'mktime' decide on whether the time is within DST or not (value -1).
630 // 656 //
631 int const _isdst{ (luaG_getfield(L_, StackIndex{ 1 }, "isdst") == LuaType::BOOLEAN) ? lua_toboolean(L_, -1) : -1 }; 657 int const _isdst{ (luaW_getfield(L_, StackIndex{ 1 }, "isdst") == LuaType::BOOLEAN) ? lua_toboolean(L_, -1) : -1 };
632 lua_pop(L_, 1); 658 lua_pop(L_, 1);
633 STACK_CHECK(L_, 0); 659 STACK_CHECK(L_, 0);
634 660
@@ -658,6 +684,7 @@ namespace {
658 { Universe::kFinally, Universe::InitializeFinalizer }, 684 { Universe::kFinally, Universe::InitializeFinalizer },
659 { "linda", LG_linda }, 685 { "linda", LG_linda },
660 { "nameof", LG_nameof }, 686 { "nameof", LG_nameof },
687 { "thread_priority_range", LG_thread_priority_range },
661 { "now_secs", LG_now_secs }, 688 { "now_secs", LG_now_secs },
662 { "register", lanes_register }, 689 { "register", lanes_register },
663 { "set_singlethreaded", LG_set_singlethreaded }, 690 { "set_singlethreaded", LG_set_singlethreaded },
@@ -692,8 +719,8 @@ LUAG_FUNC(configure)
692 719
693 Universe* _U{ Universe::Get(L_) }; 720 Universe* _U{ Universe::Get(L_) };
694 bool const _from_master_state{ _U == nullptr }; 721 bool const _from_master_state{ _U == nullptr };
695 std::string_view const _name{ luaG_checkstring(L_, StackIndex{ lua_upvalueindex(1) }) }; 722 std::string_view const _name{ luaW_checkstring(L_, StackIndex{ lua_upvalueindex(1) }) };
696 LUA_ASSERT(L_, luaG_type(L_, StackIndex{ 1 }) == LuaType::TABLE); 723 LUA_ASSERT(L_, luaW_type(L_, StackIndex{ 1 }) == LuaType::TABLE);
697 724
698 STACK_GROW(L_, 4); 725 STACK_GROW(L_, 4);
699 STACK_CHECK_START_ABS(L_, 1); // L_: settings 726 STACK_CHECK_START_ABS(L_, 1); // L_: settings
@@ -703,7 +730,7 @@ LUAG_FUNC(configure)
703 730
704 if (_U == nullptr) { 731 if (_U == nullptr) {
705 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... 732 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global...
706 kLaneNameRegKey.setValue(L_, [](lua_State* L_) { luaG_pushstring(L_, "main"); }); 733 kLaneNameRegKey.setValue(L_, [](lua_State* L_) { luaW_pushstring(L_, "main"); });
707 734
708 // create the universe 735 // create the universe
709 _U = Universe::Create(L_); // L_: settings universe 736 _U = Universe::Create(L_); // L_: settings universe
@@ -719,7 +746,7 @@ LUAG_FUNC(configure)
719 lua_pushnil(L_); // L_: settings M nil 746 lua_pushnil(L_); // L_: settings M nil
720 lua_setfield(L_, -2, "configure"); // L_: settings M 747 lua_setfield(L_, -2, "configure"); // L_: settings M
721 // add functions to the module's table 748 // add functions to the module's table
722 luaG_registerlibfuncs(L_, local::sLanesFunctions); 749 luaW_registerlibfuncs(L_, local::sLanesFunctions);
723 750
724 // register core.threads() only if settings say it should be available 751 // register core.threads() only if settings say it should be available
725 if (_U->tracker.isActive()) { 752 if (_U->tracker.isActive()) {
@@ -744,7 +771,7 @@ LUAG_FUNC(configure)
744 lua_pushcclosure(L_, LG_require, 1); // L_: settings M lanes.require 771 lua_pushcclosure(L_, LG_require, 1); // L_: settings M lanes.require
745 lua_setfield(L_, -2, "require"); // L_: settings M 772 lua_setfield(L_, -2, "require"); // L_: settings M
746 773
747 luaG_pushstring( 774 luaW_pushstring(
748 L_, 775 L_,
749 "%d.%d.%d", 776 "%d.%d.%d",
750 LANES_VERSION_MAJOR, 777 LANES_VERSION_MAJOR,
@@ -753,9 +780,6 @@ LUAG_FUNC(configure)
753 ); // L_: settings M VERSION 780 ); // L_: settings M VERSION
754 lua_setfield(L_, -2, "version"); // L_: settings M 781 lua_setfield(L_, -2, "version"); // L_: settings M
755 782
756 lua_pushinteger(L_, kThreadPrioMax); // L_: settings M kThreadPrioMax
757 lua_setfield(L_, -2, "max_prio"); // L_: settings M
758
759 kCancelError.pushKey(L_); // L_: settings M kCancelError 783 kCancelError.pushKey(L_); // L_: settings M kCancelError
760 lua_setfield(L_, -2, "cancel_error"); // L_: settings M 784 lua_setfield(L_, -2, "cancel_error"); // L_: settings M
761 785
@@ -779,7 +803,7 @@ LUAG_FUNC(configure)
779 // don't do this when called during the initialization of a new lane, 803 // don't do this when called during the initialization of a new lane,
780 // because we will do it after on_state_create() is called, 804 // because we will do it after on_state_create() is called,
781 // and we don't want to skip _G because of caching in case globals are created then 805 // and we don't want to skip _G because of caching in case globals are created then
782 luaG_pushglobaltable(L_); // L_: settings M _G 806 luaW_pushglobaltable(L_); // L_: settings M _G
783 tools::PopulateFuncLookupTable(L_, kIdxTop, {}); 807 tools::PopulateFuncLookupTable(L_, kIdxTop, {});
784 lua_pop(L_, 1); // L_: settings M 808 lua_pop(L_, 1); // L_: settings M
785 } 809 }
@@ -859,10 +883,10 @@ LANES_API int luaopen_lanes_core(lua_State* const L_)
859 883
860 // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too 884 // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too
861 if constexpr (LUAJIT_FLAVOR() == 0) { 885 if constexpr (LUAJIT_FLAVOR() == 0) {
862 if (luaG_getmodule(L_, LUA_JITLIBNAME) != LuaType::NIL) 886 if (luaW_getmodule(L_, LUA_JITLIBNAME) != LuaType::NIL)
863 raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT"); 887 raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT");
864 } else { 888 } else {
865 if (luaG_getmodule(L_, LUA_JITLIBNAME) == LuaType::NIL) 889 if (luaW_getmodule(L_, LUA_JITLIBNAME) == LuaType::NIL)
866 raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua"); 890 raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua");
867 } 891 }
868 lua_pop(L_, 1); // L_: 892 lua_pop(L_, 1); // L_: