aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp42
1 files changed, 22 insertions, 20 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index b3f7be7..7b730cd 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -205,32 +205,33 @@ LUAG_FUNC(register)
205 205
206// ################################################################################################# 206// #################################################################################################
207 207
208//--- 208//--- [] means can be nil
209// lane_ud = lane_new( function 209// lane_ud = lane_new( function
210// , [libs_str] 210// , [libs_str]
211// , [priority_int=0] 211// , [priority_int]
212// , [globals_tbl] 212// , [globals_tbl]
213// , [package_tbl] 213// , [package_tbl]
214// , [required_tbl] 214// , [required_tbl]
215// , [gc_cb_func] 215// , [gc_cb_func]
216// , [name] 216// , [name]
217// , error_trace_level
217// [, ... args ...]) 218// [, ... args ...])
218// 219//
219// Upvalues: metatable to use for 'lane_ud' 220// Upvalues: metatable to use for 'lane_ud'
220// 221//
221LUAG_FUNC(lane_new) 222LUAG_FUNC(lane_new)
222{ 223{
223 // first 8 args: func libs priority globals package required gc_cb name 224 // first 9 args: func libs priority globals package required gc_cb name error_trace_level
224 char const* const _libs_str{ lua_tostring(L_, 2) }; 225 char const* const _libs_str{ lua_tostring(L_, 2) };
225 bool const _have_priority{ !lua_isnoneornil(L_, 3) }; 226 bool const _have_priority{ !lua_isnoneornil(L_, 3) };
226 int const _priority{ _have_priority ? static_cast<int>(lua_tointeger(L_, 3)) : kThreadPrioDefault };
227 int const _globals_idx{ lua_isnoneornil(L_, 4) ? 0 : 4 }; 227 int const _globals_idx{ lua_isnoneornil(L_, 4) ? 0 : 4 };
228 int const _package_idx{ lua_isnoneornil(L_, 5) ? 0 : 5 }; 228 int const _package_idx{ lua_isnoneornil(L_, 5) ? 0 : 5 };
229 int const _required_idx{ lua_isnoneornil(L_, 6) ? 0 : 6 }; 229 int const _required_idx{ lua_isnoneornil(L_, 6) ? 0 : 6 };
230 int const _gc_cb_idx{ lua_isnoneornil(L_, 7) ? 0 : 7 }; 230 int const _gc_cb_idx{ lua_isnoneornil(L_, 7) ? 0 : 7 };
231 int const _name_idx{ lua_isnoneornil(L_, 8) ? 0 : 8 }; 231 int const _name_idx{ lua_isnoneornil(L_, 8) ? 0 : 8 };
232 int const _error_trace_level_idx{ 9 };
232 233
233 static constexpr int kFixedArgsIdx{ 8 }; 234 static constexpr int kFixedArgsIdx{ 9 };
234 int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; 235 int const _nargs{ lua_gettop(L_) - kFixedArgsIdx };
235 Universe* const _U{ universe_get(L_) }; 236 Universe* const _U{ universe_get(L_) };
236 LUA_ASSERT(L_, _nargs >= 0); 237 LUA_ASSERT(L_, _nargs >= 0);
@@ -238,6 +239,7 @@ LUAG_FUNC(lane_new)
238 // public Lanes API accepts a generic range -3/+3 239 // public Lanes API accepts a generic range -3/+3
239 // that will be remapped into the platform-specific scheduler priority scheme 240 // that will be remapped into the platform-specific scheduler priority scheme
240 // On some platforms, -3 is equivalent to -2 and +3 to +2 241 // On some platforms, -3 is equivalent to -2 and +3 to +2
242 int const _priority{ _have_priority ? static_cast<int>(lua_tointeger(L_, 3)) : kThreadPrioDefault };
241 if (_have_priority && (_priority < kThreadPrioMin || _priority > kThreadPrioMax)) { 243 if (_have_priority && (_priority < kThreadPrioMin || _priority > kThreadPrioMax)) {
242 raise_luaL_error(L_, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _priority); 244 raise_luaL_error(L_, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _priority);
243 } 245 }
@@ -246,11 +248,11 @@ LUAG_FUNC(lane_new)
246 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END(_U))); 248 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END(_U)));
247 249
248 // populate with selected libraries at the same time. 250 // populate with selected libraries at the same time.
249 lua_State* const _L2{ luaG_newstate(_U, SourceState{ L_ }, _libs_str) }; // L_: [8 args] ... L2: 251 lua_State* const _L2{ luaG_newstate(_U, SourceState{ L_ }, _libs_str) }; // L_: [9 args] ... L2:
250 STACK_CHECK_START_REL(_L2, 0); 252 STACK_CHECK_START_REL(_L2, 0);
251 253
252 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 254 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
253 Lane* const _lane{ new (_U) Lane{ _U, _L2 } }; 255 Lane* const _lane{ new (_U) Lane{ _U, _L2, static_cast<Lane::ErrorTraceLevel>(lua_tointeger(L_, _error_trace_level_idx)) } };
254 if (_lane == nullptr) { 256 if (_lane == nullptr) {
255 raise_luaL_error(L_, "could not create lane: out of memory"); 257 raise_luaL_error(L_, "could not create lane: out of memory");
256 } 258 }
@@ -410,7 +412,7 @@ LUAG_FUNC(lane_new)
410 lua_pop(_L2, 1); // L_: [8 args] args... n "modname" L2: 412 lua_pop(_L2, 1); // L_: [8 args] args... n "modname" L2:
411 } 413 }
412 } 414 }
413 lua_pop(L_, 1); // L_: func libs priority globals package required gc_cb [... args ...] n 415 lua_pop(L_, 1); // L_: func libs priority globals package required gc_cb [... args ...] n
414 ++_nbRequired; 416 ++_nbRequired;
415 } // L_: [8 args] args... 417 } // L_: [8 args] args...
416 } 418 }
@@ -443,35 +445,36 @@ LUAG_FUNC(lane_new)
443 STACK_CHECK(_L2, 0); 445 STACK_CHECK(_L2, 0);
444 446
445 // Lane main function 447 // Lane main function
448 int const errorHandlerCount{ _lane->pushErrorHandler() }; // L2: eh?
446 LuaType const _func_type{ lua_type_as_enum(L_, 1) }; 449 LuaType const _func_type{ lua_type_as_enum(L_, 1) };
447 if (_func_type == LuaType::FUNCTION) { 450 if (_func_type == LuaType::FUNCTION) {
448 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END(_U))); 451 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END(_U)));
449 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); 452 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U });
450 lua_pushvalue(L_, 1); // L_: [8 args] args... func L2: 453 lua_pushvalue(L_, 1); // L_: [8 args] args... func L2: eh?
451 InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; 454 InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} };
452 InterCopyResult const _res{ _c.inter_move(1) }; // L_: [8 args] args... L2: func 455 InterCopyResult const _res{ _c.inter_move(1) }; // L_: [8 args] args... L2: eh? func
453 if (_res != InterCopyResult::Success) { 456 if (_res != InterCopyResult::Success) {
454 raise_luaL_error(L_, "tried to copy unsupported types"); 457 raise_luaL_error(L_, "tried to copy unsupported types");
455 } 458 }
456 } else if (_func_type == LuaType::STRING) { 459 } else if (_func_type == LuaType::STRING) {
457 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END(_U))); 460 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END(_U)));
458 // compile the string 461 // compile the string
459 if (luaL_loadstring(_L2, lua_tostring(L_, 1)) != 0) { // L_: [8 args] args... L2: func 462 if (luaL_loadstring(_L2, lua_tostring(L_, 1)) != 0) { // L_: [8 args] args... L2: eh? func
460 raise_luaL_error(L_, "error when parsing lane function code"); 463 raise_luaL_error(L_, "error when parsing lane function code");
461 } 464 }
462 } else { 465 } else {
463 raise_luaL_error(L_, "Expected function, got %s", lua_typename(L_, _func_type)); 466 raise_luaL_error(L_, "Expected function, got %s", lua_typename(L_, _func_type));
464 } 467 }
465 STACK_CHECK(L_, 0); 468 STACK_CHECK(L_, 0);
466 STACK_CHECK(_L2, 1); 469 STACK_CHECK(_L2, errorHandlerCount + 1);
467 LUA_ASSERT(L_, lua_isfunction(_L2, 1)); 470 LUA_ASSERT(L_, lua_isfunction(_L2, errorHandlerCount + 1));
468 471
469 // revive arguments 472 // revive arguments
470 if (_nargs > 0) { 473 if (_nargs > 0) {
471 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END(_U))); 474 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END(_U)));
472 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); 475 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U });
473 InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; 476 InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} };
474 InterCopyResult const res{ _c.inter_move(_nargs) }; // L_: [8 args] L2: func args... 477 InterCopyResult const res{ _c.inter_move(_nargs) }; // L_: [8 args] L2: eh? func args...
475 if (res != InterCopyResult::Success) { 478 if (res != InterCopyResult::Success) {
476 raise_luaL_error(L_, "tried to copy unsupported types"); 479 raise_luaL_error(L_, "tried to copy unsupported types");
477 } 480 }
@@ -480,8 +483,8 @@ LUAG_FUNC(lane_new)
480 LUA_ASSERT(L_, lua_gettop(L_) == kFixedArgsIdx); 483 LUA_ASSERT(L_, lua_gettop(L_) == kFixedArgsIdx);
481 484
482 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). 485 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
483 kLanePointerRegKey.setValue(_L2, [lane = _lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); });// L_: [8 args] L2: func args... 486 kLanePointerRegKey.setValue(_L2, [lane = _lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); });// L_: [8 args] L2: eh? func args...
484 STACK_CHECK(_L2, 1 + _nargs); 487 STACK_CHECK(_L2, errorHandlerCount + 1 + _nargs);
485 488
486 STACK_CHECK_RESET_REL(L_, 0); 489 STACK_CHECK_RESET_REL(L_, 0);
487 // all went well, the lane's thread can start working 490 // all went well, the lane's thread can start working
@@ -579,7 +582,7 @@ LUAG_FUNC(wakeup_conv)
579// ######################################## Module linkage ######################################### 582// ######################################## Module linkage #########################################
580// ################################################################################################# 583// #################################################################################################
581 584
582extern int LG_linda(lua_State* L_); 585extern LUAG_FUNC(linda);
583 586
584namespace global { 587namespace global {
585 static struct luaL_Reg const sLanesFunctions[] = { 588 static struct luaL_Reg const sLanesFunctions[] = {
@@ -700,9 +703,8 @@ LUAG_FUNC(configure)
700 STACK_CHECK(L_, 2); 703 STACK_CHECK(L_, 2);
701 704
702 // prepare the metatable for threads 705 // prepare the metatable for threads
703 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } 706 // contains keys: { __gc, __index, cancel, join, get_debug_threadname }
704 Lane::PushMetatable(L_); 707 Lane::PushMetatable(L_); // L_: settings M {lane_mt}
705
706 lua_pushcclosure(L_, LG_lane_new, 1); // L_: settings M lane_new 708 lua_pushcclosure(L_, LG_lane_new, 1); // L_: settings M lane_new
707 lua_setfield(L_, -2, "lane_new"); // L_: settings M 709 lua_setfield(L_, -2, "lane_new"); // L_: settings M
708 710