diff options
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r-- | src/lanes.cpp | 70 |
1 files changed, 27 insertions, 43 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp index d027cff..87edb02 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -206,13 +206,16 @@ static void securize_debug_threadname(lua_State* L_, Lane* lane_) | |||
206 | { | 206 | { |
207 | STACK_CHECK_START_REL(L_, 0); | 207 | STACK_CHECK_START_REL(L_, 0); |
208 | STACK_GROW(L_, 3); | 208 | STACK_GROW(L_, 3); |
209 | lua_getiuservalue(L_, 1, 1); | 209 | // a Lane's uservalue should be a table |
210 | lua_newtable(L_); | 210 | lua_getiuservalue(L_, 1, 1); // L_: lane ... {uv} |
211 | LUA_ASSERT(L_, lua_istable(L_, -1)); | ||
212 | // we don't care about the actual key, so long as it's unique and can't collide with anything. | ||
213 | lua_newtable(L_); // L_: lane ... {uv} {} | ||
211 | // Lua 5.1 can't do 'lane_->debugName = lua_pushstring(L_, lane_->debugName);' | 214 | // Lua 5.1 can't do 'lane_->debugName = lua_pushstring(L_, lane_->debugName);' |
212 | lua_pushstring(L_, lane_->debugName); | 215 | lua_pushstring(L_, lane_->debugName); // L_: lane ... {uv} {} name |
213 | lane_->debugName = lua_tostring(L_, -1); | 216 | lane_->debugName = lua_tostring(L_, -1); |
214 | lua_rawset(L_, -3); | 217 | lua_rawset(L_, -3); // L_: lane ... {uv} |
215 | lua_pop(L_, 1); | 218 | lua_pop(L_, 1); // L_: lane |
216 | STACK_CHECK(L_, 0); | 219 | STACK_CHECK(L_, 0); |
217 | } | 220 | } |
218 | 221 | ||
@@ -253,25 +256,6 @@ Lane::~Lane() | |||
253 | // ########################################## Finalizer ############################################ | 256 | // ########################################## Finalizer ############################################ |
254 | // ################################################################################################# | 257 | // ################################################################################################# |
255 | 258 | ||
256 | // Push the finalizers table on the stack. | ||
257 | // If there is no existing table, create ti. | ||
258 | static void push_finalizers_table(lua_State* L_) | ||
259 | { | ||
260 | STACK_GROW(L_, 3); | ||
261 | STACK_CHECK_START_REL(L_, 0); | ||
262 | |||
263 | kFinalizerRegKey.pushValue(L_); // L_: ? | ||
264 | if (lua_isnil(L_, -1)) { // L_: nil? | ||
265 | lua_pop(L_, 1); // L_: | ||
266 | // store a newly created table in the registry, but leave it on the stack too | ||
267 | lua_newtable(L_); // L_: t | ||
268 | kFinalizerRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); // L_: t | ||
269 | } | ||
270 | STACK_CHECK(L_, 1); | ||
271 | } | ||
272 | |||
273 | // ################################################################################################# | ||
274 | |||
275 | // void= finalizer( finalizer_func ) | 259 | // void= finalizer( finalizer_func ) |
276 | // | 260 | // |
277 | // finalizer_func( [err, stack_tbl] ) | 261 | // finalizer_func( [err, stack_tbl] ) |
@@ -283,13 +267,14 @@ LUAG_FUNC(set_finalizer) | |||
283 | { | 267 | { |
284 | luaL_argcheck(L_, lua_isfunction(L_, 1), 1, "finalizer should be a function"); | 268 | luaL_argcheck(L_, lua_isfunction(L_, 1), 1, "finalizer should be a function"); |
285 | luaL_argcheck(L_, lua_gettop(L_) == 1, 1, "too many arguments"); | 269 | luaL_argcheck(L_, lua_gettop(L_) == 1, 1, "too many arguments"); |
270 | STACK_GROW(L_, 3); | ||
286 | // Get the current finalizer table (if any), create one if it doesn't exist | 271 | // Get the current finalizer table (if any), create one if it doesn't exist |
287 | push_finalizers_table(L_); // L_: finalizer {finalisers} | 272 | std::ignore = kFinalizerRegKey.getSubTable(L_, 1, 0); // L_: finalizer {finalisers} |
288 | STACK_GROW(L_, 2); | 273 | // must cast to int, not lua_Integer, because LuaJIT signature of lua_rawseti is not the same as PUC-Lua. |
289 | lua_pushinteger(L_, lua_rawlen(L_, -1) + 1); // L_: finalizer {finalisers} idx | 274 | int const idx{ static_cast<int>(lua_rawlen(L_, -1) + 1) }; |
290 | lua_pushvalue(L_, 1); // L_: finalizer {finalisers} idx finalizer | 275 | lua_pushvalue(L_, 1); // L_: finalizer {finalisers} finalizer |
291 | lua_rawset(L_, -3); // L_: finalizer {finalisers} | 276 | lua_rawseti(L_, -2, idx); // L_: finalizer {finalisers} |
292 | lua_pop(L_, 2); // L_: | 277 | // no need to adjust the stack, Lua does this for us |
293 | return 0; | 278 | return 0; |
294 | } | 279 | } |
295 | 280 | ||
@@ -1020,13 +1005,13 @@ LUAG_FUNC(lane_new) | |||
1020 | 1005 | ||
1021 | // Create uservalue for the userdata | 1006 | // Create uservalue for the userdata |
1022 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) | 1007 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) |
1023 | lua_newtable(m_L); // m_L: ... lane uv | 1008 | lua_newtable(m_L); // m_L: ... lane {uv} |
1024 | 1009 | ||
1025 | // Store the gc_cb callback in the uservalue | 1010 | // Store the gc_cb callback in the uservalue |
1026 | if (m_gc_cb_idx > 0) { | 1011 | if (m_gc_cb_idx > 0) { |
1027 | kLaneGC.pushKey(m_L); // m_L: ... lane uv k | 1012 | kLaneGC.pushKey(m_L); // m_L: ... lane {uv} k |
1028 | lua_pushvalue(m_L, m_gc_cb_idx); // m_L: ... lane uv k gc_cb | 1013 | lua_pushvalue(m_L, m_gc_cb_idx); // m_L: ... lane {uv} k gc_cb |
1029 | lua_rawset(m_L, -3); // m_L: ... lane uv | 1014 | lua_rawset(m_L, -3); // m_L: ... lane {uv} |
1030 | } | 1015 | } |
1031 | 1016 | ||
1032 | lua_setiuservalue(m_L, -2, 1); // m_L: ... lane | 1017 | lua_setiuservalue(m_L, -2, 1); // m_L: ... lane |
@@ -1515,7 +1500,7 @@ LUAG_FUNC(threads) | |||
1515 | lua_newtable(L_); // L_: {} | 1500 | lua_newtable(L_); // L_: {} |
1516 | while (lane != TRACKING_END) { | 1501 | while (lane != TRACKING_END) { |
1517 | // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other | 1502 | // insert a { name, status } tuple, so that several lanes with the same name can't clobber each other |
1518 | lua_newtable(L_); // L_: {} {} | 1503 | lua_createtable(L_, 0, 2); // L_: {} {} |
1519 | lua_pushstring(L_, lane->debugName); // L_: {} {} "name" | 1504 | lua_pushstring(L_, lane->debugName); // L_: {} {} "name" |
1520 | lua_setfield(L_, -2, "name"); // L_: {} {} | 1505 | lua_setfield(L_, -2, "name"); // L_: {} {} |
1521 | lane->pushThreadStatus(L_); // L_: {} {} "status" | 1506 | lane->pushThreadStatus(L_); // L_: {} {} "status" |
@@ -1648,11 +1633,11 @@ LUAG_FUNC(configure) | |||
1648 | if (U == nullptr) { | 1633 | if (U == nullptr) { |
1649 | U = universe_create(L_); // L_: settings universe | 1634 | U = universe_create(L_); // L_: settings universe |
1650 | DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U }); | 1635 | DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U }); |
1651 | lua_newtable(L_); // L_: settings universe mt | 1636 | lua_createtable(L_, 0, 1); // L_: settings universe {mt} |
1652 | lua_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe mt shutdown_timeout | 1637 | lua_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout |
1653 | lua_getfield(L_, 1, "shutdown_mode"); // L_: settings universe mt shutdown_timeout shutdown_mode | 1638 | lua_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode |
1654 | lua_pushcclosure(L_, universe_gc, 2); // L_: settings universe mt universe_gc | 1639 | lua_pushcclosure(L_, universe_gc, 2); // L_: settings universe {mt} universe_gc |
1655 | lua_setfield(L_, -2, "__gc"); // L_: settings universe mt | 1640 | lua_setfield(L_, -2, "__gc"); // L_: settings universe {mt} |
1656 | lua_setmetatable(L_, -2); // L_: settings universe | 1641 | lua_setmetatable(L_, -2); // L_: settings universe |
1657 | lua_pop(L_, 1); // L_: settings | 1642 | lua_pop(L_, 1); // L_: settings |
1658 | lua_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors | 1643 | lua_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors |
@@ -1862,12 +1847,11 @@ LANES_API int luaopen_lanes_core(lua_State* L_) | |||
1862 | STACK_CHECK_START_REL(L_, 0); | 1847 | STACK_CHECK_START_REL(L_, 0); |
1863 | 1848 | ||
1864 | // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too | 1849 | // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too |
1865 | lua_getglobal(L_, "jit"); // L_: {jit?} | ||
1866 | #if LUAJIT_FLAVOR() == 0 | 1850 | #if LUAJIT_FLAVOR() == 0 |
1867 | if (!lua_isnil(L_, -1)) | 1851 | if (luaG_getmodule(L_, LUA_JITLIBNAME) != LuaType::NIL) |
1868 | raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT"); | 1852 | raise_luaL_error(L_, "Lanes is built for PUC-Lua, don't run from LuaJIT"); |
1869 | #else | 1853 | #else |
1870 | if (lua_isnil(L_, -1)) | 1854 | if (luaG_getmodule(L_, LUA_JITLIBNAME) == LuaType::NIL) |
1871 | raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua"); | 1855 | raise_luaL_error(L_, "Lanes is built for LuaJIT, don't run from PUC-Lua"); |
1872 | #endif | 1856 | #endif |
1873 | lua_pop(L_, 1); // L_: | 1857 | lua_pop(L_, 1); // L_: |