diff options
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 77 |
1 files changed, 39 insertions, 38 deletions
diff --git a/src/lanes.c b/src/lanes.c index cd1d4f1..9f6a4d6 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -1052,21 +1052,22 @@ LUAG_FUNC( lane_new) | |||
1052 | Lane** ud; | 1052 | Lane** ud; |
1053 | 1053 | ||
1054 | char const* libs_str = lua_tostring( L, 2); | 1054 | char const* libs_str = lua_tostring( L, 2); |
1055 | int const priority = (int) luaL_optinteger( L, 3, 0); | 1055 | bool_t const have_priority = !lua_isnoneornil( L, 3); |
1056 | uint_t globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; | 1056 | int const priority = have_priority ? (int) lua_tointeger( L, 3) : THREAD_PRIO_DEFAULT; |
1057 | uint_t package_idx = lua_isnoneornil( L, 5) ? 0 : 5; | 1057 | uint_t const globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; |
1058 | uint_t required_idx = lua_isnoneornil( L, 6) ? 0 : 6; | 1058 | uint_t const package_idx = lua_isnoneornil( L, 5) ? 0 : 5; |
1059 | uint_t gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; | 1059 | uint_t const required_idx = lua_isnoneornil( L, 6) ? 0 : 6; |
1060 | uint_t const gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; | ||
1060 | 1061 | ||
1061 | #define FIXED_ARGS 7 | 1062 | #define FIXED_ARGS 7 |
1062 | int const nargs = lua_gettop(L) - FIXED_ARGS; | 1063 | int const nargs = lua_gettop(L) - FIXED_ARGS; |
1063 | Universe* U = universe_get( L); | 1064 | Universe* const U = universe_get( L); |
1064 | ASSERT_L( nargs >= 0); | 1065 | ASSERT_L( nargs >= 0); |
1065 | 1066 | ||
1066 | // public Lanes API accepts a generic range -3/+3 | 1067 | // public Lanes API accepts a generic range -3/+3 |
1067 | // that will be remapped into the platform-specific scheduler priority scheme | 1068 | // that will be remapped into the platform-specific scheduler priority scheme |
1068 | // On some platforms, -3 is equivalent to -2 and +3 to +2 | 1069 | // On some platforms, -3 is equivalent to -2 and +3 to +2 |
1069 | if( priority < THREAD_PRIO_MIN || priority > THREAD_PRIO_MAX) | 1070 | if( have_priority && (priority < THREAD_PRIO_MIN || priority > THREAD_PRIO_MAX)) |
1070 | { | 1071 | { |
1071 | return luaL_error( L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, priority); | 1072 | return luaL_error( L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, priority); |
1072 | } | 1073 | } |
@@ -1076,12 +1077,12 @@ LUAG_FUNC( lane_new) | |||
1076 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1077 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1077 | 1078 | ||
1078 | // populate with selected libraries at the same time | 1079 | // populate with selected libraries at the same time |
1079 | L2 = luaG_newstate( U, L, libs_str); // L // L2 | 1080 | L2 = luaG_newstate( U, L, libs_str); // L // L2 |
1080 | 1081 | ||
1081 | STACK_GROW( L2, nargs + 3); // | 1082 | STACK_GROW( L2, nargs + 3); // |
1082 | STACK_CHECK( L2, 0); | 1083 | STACK_CHECK( L2, 0); |
1083 | 1084 | ||
1084 | STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...] | 1085 | STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...] |
1085 | STACK_CHECK( L, 0); | 1086 | STACK_CHECK( L, 0); |
1086 | 1087 | ||
1087 | // give a default "Lua" name to the thread to see VM name in Decoda debugger | 1088 | // give a default "Lua" name to the thread to see VM name in Decoda debugger |
@@ -1110,8 +1111,8 @@ LUAG_FUNC( lane_new) | |||
1110 | return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required_idx)); | 1111 | return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required_idx)); |
1111 | } | 1112 | } |
1112 | 1113 | ||
1113 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil | 1114 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil |
1114 | while( lua_next( L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" | 1115 | while( lua_next( L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname" |
1115 | { | 1116 | { |
1116 | if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired) | 1117 | if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired) |
1117 | { | 1118 | { |
@@ -1125,29 +1126,29 @@ LUAG_FUNC( lane_new) | |||
1125 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); | 1126 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END, name)); |
1126 | 1127 | ||
1127 | // require the module in the target lane | 1128 | // require the module in the target lane |
1128 | lua_getglobal( L2, "require"); // require()? | 1129 | lua_getglobal( L2, "require"); // require()? |
1129 | if( lua_isnil( L2, -1)) | 1130 | if( lua_isnil( L2, -1)) |
1130 | { | 1131 | { |
1131 | lua_pop( L2, 1); // | 1132 | lua_pop( L2, 1); // |
1132 | luaL_error( L, "cannot pre-require modules without loading 'package' library first"); | 1133 | luaL_error( L, "cannot pre-require modules without loading 'package' library first"); |
1133 | } | 1134 | } |
1134 | else | 1135 | else |
1135 | { | 1136 | { |
1136 | lua_pushlstring( L2, name, len); // require() name | 1137 | lua_pushlstring( L2, name, len); // require() name |
1137 | if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode | 1138 | if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode |
1138 | { | 1139 | { |
1139 | // propagate error to main state if any | 1140 | // propagate error to main state if any |
1140 | luaG_inter_move( U, L2, L, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error | 1141 | luaG_inter_move( U, L2, L, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error |
1141 | return lua_error( L); | 1142 | return lua_error( L); |
1142 | } | 1143 | } |
1143 | // after requiring the module, register the functions it exported in our name<->function database | 1144 | // after requiring the module, register the functions it exported in our name<->function database |
1144 | populate_func_lookup_table( L2, -1, name); | 1145 | populate_func_lookup_table( L2, -1, name); |
1145 | lua_pop( L2, 1); // | 1146 | lua_pop( L2, 1); // |
1146 | } | 1147 | } |
1147 | } | 1148 | } |
1148 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] n | 1149 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] n |
1149 | ++ nbRequired; | 1150 | ++ nbRequired; |
1150 | } // func libs priority globals package required gc_cb [... args ...] | 1151 | } // func libs priority globals package required gc_cb [... args ...] |
1151 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1152 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
1152 | } | 1153 | } |
1153 | STACK_MID( L, 0); | 1154 | STACK_MID( L, 0); |
@@ -1165,17 +1166,17 @@ LUAG_FUNC( lane_new) | |||
1165 | } | 1166 | } |
1166 | 1167 | ||
1167 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1168 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1168 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil | 1169 | lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil |
1169 | // Lua 5.2 wants us to push the globals table on the stack | 1170 | // Lua 5.2 wants us to push the globals table on the stack |
1170 | lua_pushglobaltable( L2); // _G | 1171 | lua_pushglobaltable( L2); // _G |
1171 | while( lua_next( L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v | 1172 | while( lua_next( L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v |
1172 | { | 1173 | { |
1173 | luaG_inter_copy( U, L, L2, 2, eLM_LaneBody); // _G k v | 1174 | luaG_inter_copy( U, L, L2, 2, eLM_LaneBody); // _G k v |
1174 | // assign it in L2's globals table | 1175 | // assign it in L2's globals table |
1175 | lua_rawset( L2, -3); // _G | 1176 | lua_rawset( L2, -3); // _G |
1176 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] k | 1177 | lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] k |
1177 | } // func libs priority globals package required gc_cb [... args ...] | 1178 | } // func libs priority globals package required gc_cb [... args ...] |
1178 | lua_pop( L2, 1); // | 1179 | lua_pop( L2, 1); // |
1179 | 1180 | ||
1180 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1181 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
1181 | } | 1182 | } |
@@ -1188,8 +1189,8 @@ LUAG_FUNC( lane_new) | |||
1188 | int res; | 1189 | int res; |
1189 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); | 1190 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); |
1190 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1191 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1191 | lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func | 1192 | lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func |
1192 | res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func | 1193 | res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func |
1193 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1194 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
1194 | if( res != 0) | 1195 | if( res != 0) |
1195 | { | 1196 | { |
@@ -1199,7 +1200,7 @@ LUAG_FUNC( lane_new) | |||
1199 | else if( lua_type( L, 1) == LUA_TSTRING) | 1200 | else if( lua_type( L, 1) == LUA_TSTRING) |
1200 | { | 1201 | { |
1201 | // compile the string | 1202 | // compile the string |
1202 | if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) // func | 1203 | if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) // func |
1203 | { | 1204 | { |
1204 | return luaL_error( L, "error when parsing lane function code"); | 1205 | return luaL_error( L, "error when parsing lane function code"); |
1205 | } | 1206 | } |
@@ -1214,7 +1215,7 @@ LUAG_FUNC( lane_new) | |||
1214 | int res; | 1215 | int res; |
1215 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); | 1216 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); |
1216 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1217 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1217 | res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] | 1218 | res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] |
1218 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1219 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
1219 | if( res != 0) | 1220 | if( res != 0) |
1220 | { | 1221 | { |
@@ -1267,23 +1268,23 @@ LUAG_FUNC( lane_new) | |||
1267 | 1268 | ||
1268 | // Set metatable for the userdata | 1269 | // Set metatable for the userdata |
1269 | // | 1270 | // |
1270 | lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt | 1271 | lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt |
1271 | lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane | 1272 | lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane |
1272 | STACK_MID( L, 1); | 1273 | STACK_MID( L, 1); |
1273 | 1274 | ||
1274 | // Create uservalue for the userdata | 1275 | // Create uservalue for the userdata |
1275 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) | 1276 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) |
1276 | lua_newtable( L); // func libs cancelstep priority globals package required gc_cb lane uv | 1277 | lua_newtable( L); // func libs cancelstep priority globals package required gc_cb lane uv |
1277 | 1278 | ||
1278 | // Store the gc_cb callback in the uservalue | 1279 | // Store the gc_cb callback in the uservalue |
1279 | if( gc_cb_idx > 0) | 1280 | if( gc_cb_idx > 0) |
1280 | { | 1281 | { |
1281 | push_unique_key( L, GCCB_KEY); // func libs priority globals package required gc_cb lane uv k | 1282 | push_unique_key( L, GCCB_KEY); // func libs priority globals package required gc_cb lane uv k |
1282 | lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb | 1283 | lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb |
1283 | lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv | 1284 | lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv |
1284 | } | 1285 | } |
1285 | 1286 | ||
1286 | lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane | 1287 | lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane |
1287 | 1288 | ||
1288 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). | 1289 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). |
1289 | REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] | 1290 | REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] |