diff --git a/radio/src/Makefile b/radio/src/Makefile index 8110caebd..13da2dbae 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -379,6 +379,10 @@ WATCHDOG_TEST = NO # Values = NO, YES WARNINGS_AS_ERRORS = NO +# Enable saving of Lua byte-code of all loaded scripts +# Values = NO, YES +LUA_COMPILER = NO + #------- END BUILD OPTIONS --------------------------- # Define programs and commands. @@ -1416,6 +1420,10 @@ ifeq ($(IRPROTOS), YES) CPPDEFS += -DIRPROTOS endif +ifeq ($(LUA_COMPILER), YES) + CPPDEFS += -DLUA_COMPILER +endif + #---------------- Compiler Options C++ ---------------- # -g*: generate debugging information # -O*: optimization level diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index 9b7a5f2ec..070f51401 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -40,6 +40,11 @@ #include "bin_allocator.h" #include "lua/lua_api.h" +#if defined(LUA_COMPILER) && defined(SIMU) + #include + #include +#endif + #define PERMANENT_SCRIPTS_MAX_INSTRUCTIONS (10000/100) #define MANUAL_SCRIPTS_MAX_INSTRUCTIONS (20000/100) #define SET_LUA_INSTRUCTIONS_COUNT(x) (instructionsPercent=0, lua_sethook(L, hook, LUA_MASKCOUNT, x)) @@ -228,6 +233,44 @@ void luaFree(ScriptInternalData & sid) UNPROTECT_LUA(); } +#if defined(LUA_COMPILER) && defined(SIMU) +static int luaDumpWriter(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + UINT written; + FRESULT result = f_write((FIL *)u, p, size, &written); + return (result != FR_OK && !written); +} + +static void luaCompileAndSave(const char *filename) +{ + FIL D; + char bytecodeName[1024]; + strcpy(bytecodeName, filename); + strcat(bytecodeName, "c"); + + if (f_stat(bytecodeName, 0) == FR_OK) { + return; // compiled file already exists + } + + if (f_open(&D, bytecodeName, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK) { + TRACE("Could not open Lua bytecode output file %s", bytecodeName); + return; + } + + PROTECT_LUA() { + if (luaL_loadfile(L, filename) == 0) { + lua_lock(L); + luaU_dump(L, getproto(L->top - 1), luaDumpWriter, &D, 1); + lua_unlock(L); + TRACE("Saved Lua bytecode to file %s", bytecodeName); + } + } + UNPROTECT_LUA(); + f_close(&D); +} +#endif + int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs * sio=NULL) { int init = 0; @@ -244,6 +287,10 @@ int luaLoad(const char *filename, ScriptInternalData & sid, ScriptInputsOutputs return SCRIPT_PANIC; } +#if defined(LUA_COMPILER) && defined(SIMU) + luaCompileAndSave(filename); +#endif + SET_LUA_INSTRUCTIONS_COUNT(MANUAL_SCRIPTS_MAX_INSTRUCTIONS); PROTECT_LUA() {