diff options
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/src/lanes.c b/src/lanes.c index 037e44f..ae29af2 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -114,7 +114,7 @@ THE SOFTWARE. | |||
114 | // intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed | 114 | // intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed |
115 | static void securize_debug_threadname( lua_State* L, Lane* s) | 115 | static void securize_debug_threadname( lua_State* L, Lane* s) |
116 | { | 116 | { |
117 | STACK_CHECK( L); | 117 | STACK_CHECK( L, 0); |
118 | STACK_GROW( L, 3); | 118 | STACK_GROW( L, 3); |
119 | lua_getuservalue( L, 1); | 119 | lua_getuservalue( L, 1); |
120 | lua_newtable( L); | 120 | lua_newtable( L); |
@@ -196,10 +196,9 @@ struct s_Linda; | |||
196 | static bool_t push_registry_table( lua_State* L, UniqueKey key, bool_t create) | 196 | static bool_t push_registry_table( lua_State* L, UniqueKey key, bool_t create) |
197 | { | 197 | { |
198 | STACK_GROW( L, 3); | 198 | STACK_GROW( L, 3); |
199 | STACK_CHECK( L); | 199 | STACK_CHECK( L, 0); |
200 | push_unique_key( L, key); // key | ||
201 | lua_rawget( L, LUA_REGISTRYINDEX); // t? | ||
202 | 200 | ||
201 | REGISTRY_GET( L, key); // ? | ||
203 | if( lua_isnil( L, -1)) // nil? | 202 | if( lua_isnil( L, -1)) // nil? |
204 | { | 203 | { |
205 | lua_pop( L, 1); // | 204 | lua_pop( L, 1); // |
@@ -1179,7 +1178,7 @@ LUAG_FUNC( require) | |||
1179 | char const* name = lua_tostring( L, 1); | 1178 | char const* name = lua_tostring( L, 1); |
1180 | int const nargs = lua_gettop( L); | 1179 | int const nargs = lua_gettop( L); |
1181 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); | 1180 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); |
1182 | STACK_CHECK( L); | 1181 | STACK_CHECK( L, 0); |
1183 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); | 1182 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); |
1184 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1183 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1185 | lua_pushvalue( L, lua_upvalueindex(1)); // "name" require | 1184 | lua_pushvalue( L, lua_upvalueindex(1)); // "name" require |
@@ -1204,7 +1203,7 @@ LUAG_FUNC( register) | |||
1204 | lua_settop( L, 2); | 1203 | lua_settop( L, 2); |
1205 | luaL_argcheck( L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); | 1204 | luaL_argcheck( L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); |
1206 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); | 1205 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); |
1207 | STACK_CHECK( L); // "name" mod_table | 1206 | STACK_CHECK( L, 0); // "name" mod_table |
1208 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); | 1207 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); |
1209 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1208 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1210 | populate_func_lookup_table( L, -1, name); | 1209 | populate_func_lookup_table( L, -1, name); |
@@ -1265,10 +1264,10 @@ LUAG_FUNC( lane_new) | |||
1265 | L2 = luaG_newstate( U, L, libs_str); // L // L2 | 1264 | L2 = luaG_newstate( U, L, libs_str); // L // L2 |
1266 | 1265 | ||
1267 | STACK_GROW( L2, nargs + 3); // | 1266 | STACK_GROW( L2, nargs + 3); // |
1268 | STACK_CHECK( L2); | 1267 | STACK_CHECK( L2, 0); |
1269 | 1268 | ||
1270 | STACK_GROW( L, 3); // func libs cancelstep priority globals package required gc_cb [... args ...] | 1269 | STACK_GROW( L, 3); // func libs cancelstep priority globals package required gc_cb [... args ...] |
1271 | STACK_CHECK( L); | 1270 | STACK_CHECK( L, 0); |
1272 | 1271 | ||
1273 | // give a default "Lua" name to the thread to see VM name in Decoda debugger | 1272 | // give a default "Lua" name to the thread to see VM name in Decoda debugger |
1274 | lua_pushfstring( L2, "Lane #%p", L2); // "..." | 1273 | lua_pushfstring( L2, "Lane #%p", L2); // "..." |
@@ -1409,7 +1408,7 @@ LUAG_FUNC( lane_new) | |||
1409 | } | 1408 | } |
1410 | STACK_END( L, -nargs); | 1409 | STACK_END( L, -nargs); |
1411 | ASSERT_L( lua_gettop( L) == FIXED_ARGS); | 1410 | ASSERT_L( lua_gettop( L) == FIXED_ARGS); |
1412 | STACK_CHECK( L); | 1411 | STACK_CHECK( L, 0); |
1413 | STACK_MID( L2, 1 + nargs); | 1412 | STACK_MID( L2, 1 + nargs); |
1414 | 1413 | ||
1415 | // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) | 1414 | // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) |
@@ -1463,9 +1462,7 @@ LUAG_FUNC( lane_new) | |||
1463 | lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane | 1462 | lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane |
1464 | 1463 | ||
1465 | // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive). | 1464 | // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive). |
1466 | push_unique_key( L2, CANCEL_TEST_KEY); // func [... args ...] k | 1465 | REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] |
1467 | lua_pushlightuserdata( L2, s); // func [... args ...] k s | ||
1468 | lua_rawset( L2, LUA_REGISTRYINDEX); // func [... args ...] | ||
1469 | 1466 | ||
1470 | if( cancelstep_idx) | 1467 | if( cancelstep_idx) |
1471 | { | 1468 | { |
@@ -1679,7 +1676,7 @@ LUAG_FUNC( thread_join) | |||
1679 | return 2; | 1676 | return 2; |
1680 | } | 1677 | } |
1681 | 1678 | ||
1682 | STACK_CHECK( L); | 1679 | STACK_CHECK( L, 0); |
1683 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now | 1680 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now |
1684 | 1681 | ||
1685 | if( s->mstatus == KILLED) // OS thread was killed if thread_cancel was forced | 1682 | if( s->mstatus == KILLED) // OS thread was killed if thread_cancel was forced |
@@ -1961,7 +1958,7 @@ LUAG_FUNC( wakeup_conv ) | |||
1961 | // .yday (day of the year) | 1958 | // .yday (day of the year) |
1962 | // .isdst (daylight saving on/off) | 1959 | // .isdst (daylight saving on/off) |
1963 | 1960 | ||
1964 | STACK_CHECK( L); | 1961 | STACK_CHECK( L, 0); |
1965 | lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); | 1962 | lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1966 | lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); | 1963 | lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); |
1967 | lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); | 1964 | lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); |
@@ -1975,7 +1972,7 @@ LUAG_FUNC( wakeup_conv ) | |||
1975 | lua_getfield( L, 1, "isdst" ); | 1972 | lua_getfield( L, 1, "isdst" ); |
1976 | isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1; | 1973 | isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1; |
1977 | lua_pop(L,1); | 1974 | lua_pop(L,1); |
1978 | STACK_END( L, 0); | 1975 | STACK_END( L, 0); |
1979 | 1976 | ||
1980 | t.tm_year= year-1900; | 1977 | t.tm_year= year-1900; |
1981 | t.tm_mon= month-1; // 0..11 | 1978 | t.tm_mon= month-1; // 0..11 |
@@ -2101,7 +2098,7 @@ LUAG_FUNC( configure) | |||
2101 | #endif // THREADAPI == THREADAPI_PTHREAD | 2098 | #endif // THREADAPI == THREADAPI_PTHREAD |
2102 | 2099 | ||
2103 | STACK_GROW( L, 4); | 2100 | STACK_GROW( L, 4); |
2104 | STACK_CHECK( L); | 2101 | STACK_CHECK_ABS( L, 1); // settings |
2105 | 2102 | ||
2106 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); | 2103 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); |
2107 | DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth); | 2104 | DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth); |
@@ -2121,7 +2118,7 @@ LUAG_FUNC( configure) | |||
2121 | } | 2118 | } |
2122 | } | 2119 | } |
2123 | lua_pop( L, 1); // settings | 2120 | lua_pop( L, 1); // settings |
2124 | STACK_MID( L, 0); | 2121 | STACK_MID( L, 1); |
2125 | 2122 | ||
2126 | // grab or create the universe | 2123 | // grab or create the universe |
2127 | if( U == NULL) | 2124 | if( U == NULL) |
@@ -2155,13 +2152,13 @@ LUAG_FUNC( configure) | |||
2155 | U->selfdestruct_first = SELFDESTRUCT_END; | 2152 | U->selfdestruct_first = SELFDESTRUCT_END; |
2156 | initialize_on_state_create( U, L); | 2153 | initialize_on_state_create( U, L); |
2157 | init_keepers( U, L); | 2154 | init_keepers( U, L); |
2158 | STACK_MID( L, 0); | 2155 | STACK_MID( L, 1); |
2159 | 2156 | ||
2160 | // Initialize 'timer_deep'; a common Linda object shared by all states | 2157 | // Initialize 'timer_deep'; a common Linda object shared by all states |
2161 | lua_pushcfunction( L, LG_linda); // settings lanes.linda | 2158 | lua_pushcfunction( L, LG_linda); // settings lanes.linda |
2162 | lua_pushliteral( L, "lanes-timer"); // settings lanes.linda "lanes-timer" | 2159 | lua_pushliteral( L, "lanes-timer"); // settings lanes.linda "lanes-timer" |
2163 | lua_call( L, 1, 1); // settings linda | 2160 | lua_call( L, 1, 1); // settings linda |
2164 | STACK_MID( L, 1); | 2161 | STACK_MID( L, 2); |
2165 | 2162 | ||
2166 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer | 2163 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer |
2167 | U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); | 2164 | U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); |
@@ -2169,7 +2166,7 @@ LUAG_FUNC( configure) | |||
2169 | ++ U->timer_deep->refcount; | 2166 | ++ U->timer_deep->refcount; |
2170 | lua_pop( L, 1); // settings | 2167 | lua_pop( L, 1); // settings |
2171 | } | 2168 | } |
2172 | STACK_MID( L, 0); | 2169 | STACK_MID( L, 1); |
2173 | 2170 | ||
2174 | // Serialize calls to 'require' from now on, also in the primary state | 2171 | // Serialize calls to 'require' from now on, also in the primary state |
2175 | serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); | 2172 | serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); |
@@ -2189,7 +2186,7 @@ LUAG_FUNC( configure) | |||
2189 | lua_setfield( L, -2, "threads"); // settings M | 2186 | lua_setfield( L, -2, "threads"); // settings M |
2190 | } | 2187 | } |
2191 | #endif // HAVE_LANE_TRACKING | 2188 | #endif // HAVE_LANE_TRACKING |
2192 | STACK_MID( L, 1); | 2189 | STACK_MID( L, 2); |
2193 | 2190 | ||
2194 | { | 2191 | { |
2195 | char const* errmsg; | 2192 | char const* errmsg; |
@@ -2200,7 +2197,7 @@ LUAG_FUNC( configure) | |||
2200 | } | 2197 | } |
2201 | lua_setfield( L, -2, "timer_gateway"); // settings M | 2198 | lua_setfield( L, -2, "timer_gateway"); // settings M |
2202 | } | 2199 | } |
2203 | STACK_MID( L, 1); | 2200 | STACK_MID( L, 2); |
2204 | 2201 | ||
2205 | // prepare the metatable for threads | 2202 | // prepare the metatable for threads |
2206 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } | 2203 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } |
@@ -2244,9 +2241,10 @@ LUAG_FUNC( configure) | |||
2244 | push_unique_key( L, CANCEL_ERROR); // settings M CANCEL_ERROR | 2241 | push_unique_key( L, CANCEL_ERROR); // settings M CANCEL_ERROR |
2245 | lua_setfield( L, -2, "cancel_error"); // settings M | 2242 | lua_setfield( L, -2, "cancel_error"); // settings M |
2246 | 2243 | ||
2244 | STACK_MID( L, 2); // reference stack contains only the function argument 'settings' | ||
2247 | // we'll need this every time we transfer some C function from/to this state | 2245 | // we'll need this every time we transfer some C function from/to this state |
2248 | lua_newtable( L); | 2246 | REGISTRY_SET( L, LOOKUP_REGKEY, lua_newtable( L)); |
2249 | lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); | 2247 | STACK_MID( L, 2); |
2250 | 2248 | ||
2251 | // register all native functions found in that module in the transferable functions database | 2249 | // register all native functions found in that module in the transferable functions database |
2252 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) | 2250 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) |
@@ -2264,11 +2262,11 @@ LUAG_FUNC( configure) | |||
2264 | populate_func_lookup_table( L, -1, NULL); | 2262 | populate_func_lookup_table( L, -1, NULL); |
2265 | lua_pop( L, 1); // settings M | 2263 | lua_pop( L, 1); // settings M |
2266 | } | 2264 | } |
2267 | // set _R[CONFIG_REGKEY] = settings | 2265 | lua_pop( L, 1); // settings |
2268 | lua_pushvalue( L, -2); // settings M settings | 2266 | |
2269 | lua_setfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); // settings M | 2267 | // set _R[CONFIG_REGKEY] = settings |
2270 | lua_pop( L, 1); // settings | 2268 | REGISTRY_SET( L, CONFIG_REGKEY, lua_pushvalue( L, -2)); // -2 because CONFIG_REGKEY is pushed before the value itself |
2271 | STACK_END( L, 0); | 2269 | STACK_END( L, 1); |
2272 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); | 2270 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); |
2273 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 2271 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
2274 | // Return the settings table | 2272 | // Return the settings table |
@@ -2331,7 +2329,7 @@ int LANES_API luaopen_lanes_core( lua_State* L) | |||
2331 | #endif // defined PLATFORM_WIN32 && !defined NDEBUG | 2329 | #endif // defined PLATFORM_WIN32 && !defined NDEBUG |
2332 | 2330 | ||
2333 | STACK_GROW( L, 4); | 2331 | STACK_GROW( L, 4); |
2334 | STACK_CHECK( L); | 2332 | STACK_CHECK( L, 0); |
2335 | 2333 | ||
2336 | // Create main module interface table | 2334 | // Create main module interface table |
2337 | // we only have 1 closure, which must be called to configure Lanes | 2335 | // we only have 1 closure, which must be called to configure Lanes |
@@ -2339,7 +2337,7 @@ int LANES_API luaopen_lanes_core( lua_State* L) | |||
2339 | lua_pushvalue( L, 1); // M "lanes.core" | 2337 | lua_pushvalue( L, 1); // M "lanes.core" |
2340 | lua_pushvalue( L, -2); // M "lanes.core" M | 2338 | lua_pushvalue( L, -2); // M "lanes.core" M |
2341 | lua_pushcclosure( L, LG_configure, 2); // M LG_configure() | 2339 | lua_pushcclosure( L, LG_configure, 2); // M LG_configure() |
2342 | lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); // M LG_configure() settings | 2340 | REGISTRY_GET( L, CONFIG_REGKEY); // M LG_configure() settings |
2343 | if( !lua_isnil( L, -1)) // this is not the first require "lanes.core": call configure() immediately | 2341 | if( !lua_isnil( L, -1)) // this is not the first require "lanes.core": call configure() immediately |
2344 | { | 2342 | { |
2345 | lua_pushvalue( L, -1); // M LG_configure() settings settings | 2343 | lua_pushvalue( L, -1); // M LG_configure() settings settings |
@@ -2370,7 +2368,7 @@ static int default_luaopen_lanes( lua_State* L) | |||
2370 | // call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application | 2368 | // call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application |
2371 | void LANES_API luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) | 2369 | void LANES_API luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) |
2372 | { | 2370 | { |
2373 | STACK_CHECK( L); | 2371 | STACK_CHECK( L, 0); |
2374 | // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded | 2372 | // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded |
2375 | luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core | 2373 | luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core |
2376 | lua_pop( L, 1); // ... | 2374 | lua_pop( L, 1); // ... |