From 3bff9011d8a7baed3281a3be3c664fc7d0bdc41c Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 21 Jan 2022 16:16:13 +0200 Subject: [PATCH 1/2] LUA_EnumLib optimizations for constant value access - constants are stored into _G after first use - made LUA_EvalMath's dedicated Lua state permanent so it can also benefit from these optimizations --- src/deh_lua.c | 169 +++++++++++++++++++++++++++++------------------ src/deh_lua.h | 15 +++++ src/deh_soc.c | 3 + src/lua_script.c | 23 ++++--- 4 files changed, 134 insertions(+), 76 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index a2ffca95b..0bd906c13 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -10,20 +10,7 @@ /// \file deh_lua.c /// \brief Lua SOC library -#include "g_game.h" -#include "s_sound.h" -#include "z_zone.h" -#include "m_menu.h" -#include "m_misc.h" -#include "p_local.h" -#include "st_stuff.h" -#include "fastcmp.h" -#include "lua_script.h" -#include "lua_libs.h" - -#include "dehacked.h" #include "deh_lua.h" -#include "deh_tables.h" // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -89,6 +76,8 @@ static inline int lib_freeslot(lua_State *L) strncpy(sprnames[j],word,4); //sprnames[j][4] = 0; used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now. + // Lua needs to update the value in _G if it exists + LUA_UpdateSprName(word, j); lua_pushinteger(L, j); r++; break; @@ -216,18 +205,27 @@ static int lib_dummysuper(lua_State *L) return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions being called by state changes!"); // convoluted, I know. @_@;; } -static inline int lib_getenum(lua_State *L) +static void CacheAndPushConstant(lua_State *L, const char *name, lua_Integer value) { - const char *word, *p; + // "cache" into _G + lua_pushstring(L, name); + lua_pushinteger(L, value); + lua_rawset(L, LUA_GLOBALSINDEX); + // push + lua_pushinteger(L, value); +} + +// Search for a matching constant variable. +// Result is stored into _G for faster subsequent use. (Except for SPR_ in the SOC parser) +static int ScanConstants(lua_State *L, boolean mathlib, const char *word) +{ + const char *p; fixed_t i; - boolean mathlib = lua_toboolean(L, lua_upvalueindex(1)); - if (lua_type(L,2) != LUA_TSTRING) - return 0; - word = lua_tostring(L,2); + if (strlen(word) == 1) { // Assume sprite frame if length 1. if (*word >= 'A' && *word <= '~') { - lua_pushinteger(L, *word-'A'); + CacheAndPushConstant(L, word, *word-'A'); return 1; } if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word); @@ -237,7 +235,7 @@ static inline int lib_getenum(lua_State *L) p = word+3; for (i = 0; MOBJFLAG_LIST[i]; i++) if (fastcmp(p, MOBJFLAG_LIST[i])) { - lua_pushinteger(L, ((lua_Integer)1< Date: Tue, 25 Jan 2022 00:43:38 +0200 Subject: [PATCH 2/2] Fix Lua stack overflow in LUA_UpdateSprName --- src/deh_lua.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 0bd906c13..1f6a0659c 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -590,11 +590,12 @@ void LUA_UpdateSprName(const char *name, lua_Integer value) if (!lua_isnil(gL, -1)) { - lua_pop(gL, 1); lua_pushstring(gL, name); lua_pushinteger(gL, value); lua_rawset(gL, LUA_GLOBALSINDEX); } + + lua_pop(gL, 1); // pop the rawget result } int LUA_EnumLib(lua_State *L)