| 321 | } |
| 322 | |
| 323 | void lua_scripts::run_next_script(lua_State *L) { |
| 324 | if (scripts == nullptr) { |
| 325 | #if defined(AP_SCRIPTING_CHECKS) && AP_SCRIPTING_CHECKS >= 1 |
| 326 | AP_HAL::panic("Lua: Attempted to run a script without any scripts queued"); |
| 327 | #endif // defined(AP_SCRIPTING_CHECKS) && AP_SCRIPTING_CHECKS >= 1 |
| 328 | return; |
| 329 | } |
| 330 | |
| 331 | uint64_t start_time_ms = AP_HAL::millis64(); |
| 332 | // strip the selected script out of the list |
| 333 | script_info *script = scripts; |
| 334 | scripts = script->next; |
| 335 | |
| 336 | // reset the hook to clear the counter |
| 337 | reset_loop_overtime(L); |
| 338 | |
| 339 | // store top of stack so we can calculate the number of return values |
| 340 | int stack_top = lua_gettop(L); |
| 341 | |
| 342 | // pop the function to the top of the stack |
| 343 | lua_rawgeti(L, LUA_REGISTRYINDEX, script->run_ref); |
| 344 | // set current environment for other users |
| 345 | AP::scripting()->set_current_env_ref(script->env_ref); |
| 346 | |
| 347 | if(lua_pcall(L, 0, LUA_MULTRET, 0)) { |
| 348 | if (overtime) { |
| 349 | // script has consumed an excessive amount of CPU time |
| 350 | set_and_print_new_error_message(MAV_SEVERITY_CRITICAL, "%s exceeded time limit", script->name); |
| 351 | } else { |
| 352 | set_and_print_new_error_message(MAV_SEVERITY_CRITICAL, "%s", get_error_object_message(L)); |
| 353 | } |
| 354 | remove_script(L, script); |
| 355 | lua_pop(L, 1); |
| 356 | return; |
| 357 | } else { |
| 358 | int returned = lua_gettop(L) - stack_top; |
| 359 | switch (returned) { |
| 360 | case 0: |
| 361 | // no time to reschedule so bail out |
| 362 | remove_script(L, script); |
| 363 | break; |
| 364 | case 2: |
| 365 | { |
| 366 | // sanity check the return types |
| 367 | if (lua_type(L, -1) != LUA_TNUMBER) { |
| 368 | set_and_print_new_error_message(MAV_SEVERITY_CRITICAL, "%s did not return a delay (0x%d)", script->name, lua_type(L, -1)); |
| 369 | lua_pop(L, 2); |
| 370 | remove_script(L, script); |
| 371 | return; |
| 372 | } |
| 373 | if (lua_type(L, -2) != LUA_TFUNCTION) { |
| 374 | set_and_print_new_error_message(MAV_SEVERITY_CRITICAL, "%s did not return a function (0x%d)", script->name, lua_type(L, -2)); |
| 375 | lua_pop(L, 2); |
| 376 | remove_script(L, script); |
| 377 | return; |
| 378 | } |
| 379 | |
| 380 | // types match the expectations, go ahead and reschedule |
nothing calls this directly
no test coverage detected