mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
Debugger: Lua - Modify Lua core to implement watchdog timer to bypass Lua hooks and improve performance
This commit is contained in:
parent
4c108d9055
commit
c7ebd57e06
8 changed files with 41 additions and 7 deletions
|
@ -46,12 +46,13 @@ LuaScriptingContext::~LuaScriptingContext()
|
|||
}
|
||||
}
|
||||
|
||||
void LuaScriptingContext::ExecutionCountHook(lua_State *lua, lua_Debug *ar)
|
||||
void LuaScriptingContext::ExecutionCountHook(lua_State *lua)
|
||||
{
|
||||
uint32_t timeout = _context->_settings->GetDebugConfig().ScriptTimeout;
|
||||
if(_context->_timer.GetElapsedMS() > timeout * 1000) {
|
||||
luaL_error(lua, (std::string("Maximum execution time (") + std::to_string(timeout) + " seconds) exceeded.").c_str());
|
||||
}
|
||||
lua_setwatchdogtimer(lua, LuaScriptingContext::ExecutionCountHook, 1000);
|
||||
}
|
||||
|
||||
void LuaScriptingContext::LuaOpenLibs(lua_State* L, bool allowIoOsAccess)
|
||||
|
@ -116,7 +117,7 @@ bool LuaScriptingContext::LoadScript(string scriptName, string scriptContent, De
|
|||
Log("Loading script...");
|
||||
if((iErr = luaL_loadbufferx(_lua, scriptContent.c_str(), scriptContent.size(), ("@" + scriptName).c_str(), nullptr)) == 0) {
|
||||
_timer.Reset();
|
||||
lua_sethook(_lua, LuaScriptingContext::ExecutionCountHook, LUA_MASKCOUNT, 1000);
|
||||
lua_setwatchdogtimer(_lua, LuaScriptingContext::ExecutionCountHook, 1000);
|
||||
if((iErr = lua_pcall(_lua, 0, LUA_MULTRET, 0)) == 0) {
|
||||
//Script loaded properly
|
||||
Log("Script loaded successfully.");
|
||||
|
@ -149,15 +150,20 @@ void LuaScriptingContext::InternalCallMemoryCallback(uint32_t addr, uint8_t &val
|
|||
return;
|
||||
}
|
||||
|
||||
_timer.Reset();
|
||||
_context = this;
|
||||
lua_sethook(_lua, LuaScriptingContext::ExecutionCountHook, LUA_MASKCOUNT, 1000);
|
||||
bool needTimerReset = true;
|
||||
lua_setwatchdogtimer(_lua, LuaScriptingContext::ExecutionCountHook, 1000);
|
||||
LuaApi::SetContext(this);
|
||||
for(MemoryCallback &callback: _callbacks[(int)type]) {
|
||||
if(callback.Type != cpuType || addr < callback.StartAddress || addr > callback.EndAddress) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(needTimerReset) {
|
||||
_timer.Reset();
|
||||
needTimerReset = false;
|
||||
}
|
||||
|
||||
int top = lua_gettop(_lua);
|
||||
lua_rawgeti(_lua, LUA_REGISTRYINDEX, callback.Reference);
|
||||
lua_pushinteger(_lua, addr);
|
||||
|
@ -183,7 +189,7 @@ int LuaScriptingContext::InternalCallEventCallback(EventType type)
|
|||
|
||||
_timer.Reset();
|
||||
_context = this;
|
||||
lua_sethook(_lua, LuaScriptingContext::ExecutionCountHook, LUA_MASKCOUNT, 1000);
|
||||
lua_setwatchdogtimer(_lua, LuaScriptingContext::ExecutionCountHook, 1000);
|
||||
LuaApi::SetContext(this);
|
||||
LuaCallHelper l(_lua);
|
||||
for(int &ref : _eventCallbacks[(int)type]) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "Utilities/Timer.h"
|
||||
|
||||
struct lua_State;
|
||||
struct lua_Debug;
|
||||
class Debugger;
|
||||
class EmuSettings;
|
||||
|
||||
|
@ -18,7 +17,7 @@ private:
|
|||
Timer _timer;
|
||||
EmuSettings* _settings = nullptr;
|
||||
|
||||
static void ExecutionCountHook(lua_State* lua, lua_Debug* ar);
|
||||
static void ExecutionCountHook(lua_State* lua);
|
||||
|
||||
void LuaOpenLibs(lua_State* L, bool allowIoOsAccess);
|
||||
|
||||
|
|
|
@ -772,12 +772,14 @@ static int skipcomment (LoadF *lf, int *cp) {
|
|||
else return 0; /* no comment */
|
||||
}
|
||||
|
||||
// ##### MESEN MODIFICATION #####
|
||||
int SANDBOX_ALLOW_LOADFILE = 0;
|
||||
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
const char *mode) {
|
||||
if (!SANDBOX_ALLOW_LOADFILE) {
|
||||
return LUA_ERRERR;
|
||||
}
|
||||
// ##### MESEN MODIFICATION #####
|
||||
|
||||
LoadF lf;
|
||||
int status, readstatus;
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#include "luaconf.h"
|
||||
#include "lua.h"
|
||||
|
||||
// ##### MESEN MODIFICATION #####
|
||||
extern int SANDBOX_ALLOW_LOADFILE;
|
||||
// ##### MESEN MODIFICATION #####
|
||||
|
||||
/* global table */
|
||||
#define LUA_GNAME "_G"
|
||||
|
|
|
@ -141,6 +141,13 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
|
|||
settraps(L->ci); /* to trace inside 'luaV_execute' */
|
||||
}
|
||||
|
||||
// ##### MESEN MODIFICATION #####
|
||||
LUA_API void lua_setwatchdogtimer(lua_State* L, lua_WatchDogHook func, int count)
|
||||
{
|
||||
L->watchdoghook = func;
|
||||
L->watchdogtimer = count;
|
||||
}
|
||||
// ##### MESEN MODIFICATION #####
|
||||
|
||||
LUA_API lua_Hook lua_gethook (lua_State *L) {
|
||||
return L->hook;
|
||||
|
|
|
@ -324,6 +324,11 @@ struct lua_State {
|
|||
int basehookcount;
|
||||
int hookcount;
|
||||
volatile l_signalT hookmask;
|
||||
|
||||
// ##### MESEN MODIFICATION #####
|
||||
int watchdogtimer;
|
||||
lua_WatchDogHook watchdoghook;
|
||||
// ##### MESEN MODIFICATION #####
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -448,6 +448,10 @@ typedef struct lua_Debug lua_Debug; /* activation record */
|
|||
/* Functions to be called by the debugger in specific events */
|
||||
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
||||
|
||||
// ##### MESEN MODIFICATION #####
|
||||
typedef void (*lua_WatchDogHook) (lua_State* L);
|
||||
// ##### MESEN MODIFICATION #####
|
||||
|
||||
|
||||
LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
|
||||
LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
|
||||
|
@ -461,6 +465,11 @@ LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
|
|||
int fidx2, int n2);
|
||||
|
||||
LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
|
||||
|
||||
// ##### MESEN MODIFICATION #####
|
||||
LUA_API void lua_setwatchdogtimer(lua_State* L, lua_WatchDogHook func, int count);
|
||||
// ##### MESEN MODIFICATION #####
|
||||
|
||||
LUA_API lua_Hook (lua_gethook) (lua_State *L);
|
||||
LUA_API int (lua_gethookmask) (lua_State *L);
|
||||
LUA_API int (lua_gethookcount) (lua_State *L);
|
||||
|
|
|
@ -1122,7 +1122,11 @@ void luaV_finishOp (lua_State *L) {
|
|||
|
||||
|
||||
/* fetch an instruction and prepare its execution */
|
||||
// ##### MESEN MODIFICATION (watchdogtimer) #####
|
||||
#define vmfetch() { \
|
||||
if (L->watchdogtimer && !--L->watchdogtimer) { \
|
||||
(*L->watchdoghook)(L); \
|
||||
} \
|
||||
if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \
|
||||
trap = luaG_traceexec(L, pc); /* handle hooks */ \
|
||||
updatebase(ci); /* correct stack */ \
|
||||
|
|
Loading…
Add table
Reference in a new issue