Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : #pragma once 16 : 17 : #include "AP_Scripting_config.h" 18 : 19 : #if AP_SCRIPTING_ENABLED 20 : 21 : #include <AP_Common/AP_Common.h> 22 : #include <AP_Param/AP_Param.h> 23 : #include <AP_HAL/ap_setjmp.h> 24 : 25 : #include <AP_Filesystem/posix_compat.h> 26 : #include <AP_Scripting/AP_Scripting.h> 27 : #include <GCS_MAVLink/GCS_MAVLink.h> 28 : #include <AP_HAL/Semaphores.h> 29 : #include <AP_MultiHeap/AP_MultiHeap.h> 30 : #include "lua_common_defs.h" 31 : 32 : #include "lua/src/lua.hpp" 33 : 34 : class lua_scripts; 35 : 36 97 : static inline lua_scripts* ls_object_from_state(lua_State *L) { 37 : // the state extra space stores a pointer to the lua_scripts object the 38 : // state is a part of, used for ls_* callback trampolines. 39 97 : return *static_cast<lua_scripts**>(lua_getextraspace(L)); 40 : } 41 : 42 : class lua_scripts 43 : { 44 : public: 45 : lua_scripts(const AP_Int32 &vm_steps, const AP_Int32 &heap_size, AP_Int8 &debug_options); 46 : 47 : ~lua_scripts(); 48 : 49 : CLASS_NO_COPY(lua_scripts); 50 : 51 : // return true if initialisation failed 52 97 : bool heap_allocated() const { return _heap.available(); } 53 : 54 : // run scripts, does not return unless an error occured 55 : void run(void); 56 : 57 : static bool overtime; // script exceeded it's execution slot, and we are bailing out 58 : 59 : private: 60 : 61 97 : static int ls_run_engine(lua_State *L) { 62 97 : return ls_object_from_state(L)->run_engine(L); 63 : }; 64 : int run_engine(lua_State *L); 65 : 66 : void create_sandbox(lua_State *L); 67 : 68 : typedef struct script_info { 69 : int env_ref; // reference to the script's environment table 70 : int run_ref; // reference to the function to run 71 : uint64_t next_run_ms; // time (in milliseconds) the script should next be run at 72 : uint32_t crc; // crc32 checksum 73 : char *name; // filename for the script // FIXME: This information should be available from Lua 74 : script_info *next; 75 : } script_info; 76 : 77 : bool load_script(lua_State *L, script_info *new_script); 78 : 79 : void reset_loop_overtime(lua_State *L); 80 : 81 : void load_all_scripts_in_dir(lua_State *L, const char *dirname); 82 : 83 : void run_next_script(lua_State *L); 84 : 85 : void remove_script(lua_State *L, script_info *script); 86 : 87 : // reschedule the script for execution. It is assumed the script is not in the list already 88 : void reschedule_script(script_info *script); 89 : 90 : script_info *scripts; // linked list of scripts to be run, sorted by next run time (soonest first) 91 : 92 : // hook will be run when CPU time for a script is exceeded 93 : // it must be static to be passed to the C API 94 : static void hook(lua_State *L, lua_Debug *ar); 95 : 96 : const AP_Int32 & _vm_steps; 97 : AP_Int8 & _debug_options; 98 : 99 272464 : bool option_is_set(AP_Scripting::DebugOption option) const { 100 272464 : return (uint8_t(_debug_options.get()) & uint8_t(option)) != 0; 101 : } 102 : 103 : static void *alloc(void *ud, void *ptr, size_t osize, size_t nsize); 104 : 105 : static MultiHeap _heap; 106 : 107 : // helper for print and log of runtime stats 108 : void update_stats(const char *name, uint32_t run_time, int total_mem, int run_mem); 109 : 110 : // must be static for bindings 111 : static void print_error(MAV_SEVERITY severity); 112 : static char *error_msg_buf; 113 : static HAL_Semaphore error_msg_buf_sem; 114 : static uint8_t print_error_count; 115 : static uint32_t last_print_ms; 116 : 117 : // XOR of crc32 of running scripts 118 : static uint32_t loaded_checksum; 119 : static uint32_t running_checksum; 120 : static HAL_Semaphore crc_sem; 121 : 122 : public: 123 : // must be static and public to allow bindings to issue non-fatal warnings 124 : static void set_and_print_new_error_message(MAV_SEVERITY severity, const char *fmt, ...) FMT_PRINTF(2,3); 125 : 126 : // return last error message, nullptr if none, must use semaphore as this is updated in the scripting thread 127 4069 : static const char* get_last_error_message() { return error_msg_buf; } 128 : 129 : // get semaphore for above error buffer 130 8138 : static AP_HAL::Semaphore* get_last_error_semaphore() { return &error_msg_buf_sem; } 131 : 132 : // Return the file checksums of running and loaded scripts 133 : static uint32_t get_loaded_checksum(); 134 : static uint32_t get_running_checksum(); 135 : 136 : }; 137 : 138 : #endif // AP_SCRIPTING_ENABLED