aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c77
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 ...]