From 18aca45673f2311215b24db42f65fa23cc2dcbc4 Mon Sep 17 00:00:00 2001 From: "BADIM-PC\\Vadim" Date: Tue, 12 Dec 2017 12:50:39 +0300 Subject: [PATCH] Impossible to exit infinite while loop #197 --- src/luaapi.c | 21 ++++++++++++++++++++- src/run.c | 12 ++++++++++++ src/ticapi.h | 3 +++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/luaapi.c b/src/luaapi.c index bf40d61..7f01694 100644 --- a/src/luaapi.c +++ b/src/luaapi.c @@ -29,6 +29,8 @@ #include "machine.h" #include "ext/moonscript.h" +#define LUA_LOC_STACK 1E8 // 100.000.000 + static const char TicMachine[] = "_TIC80"; s32 luaopen_lpeg(lua_State *L); @@ -1061,6 +1063,21 @@ static const lua_CFunction ApiFunc[] = STATIC_ASSERT(api_func, COUNT_OF(ApiKeywords) == COUNT_OF(ApiFunc)); +static void checkForceExit(lua_State *lua, lua_Debug *luadebug) +{ + tic_machine* machine = getLuaMachine(lua); + + tic_tick_data* tick = machine->data; + + if(tick->hook) + { + tick->hook(tick->data); + + if(tick->forceExit) + luaL_error(lua, "script execution was interrupted"); + } +} + static void initAPI(tic_machine* machine) { lua_pushlightuserdata(machine->lua, machine); @@ -1072,6 +1089,8 @@ static void initAPI(tic_machine* machine) registerLuaFunction(machine, lua_dofile, "dofile"); registerLuaFunction(machine, lua_loadfile, "loadfile"); + + lua_sethook(machine->lua, &checkForceExit, LUA_MASKCOUNT, LUA_LOC_STACK); } void closeLua(tic_machine* machine) @@ -1216,7 +1235,7 @@ void callLuaTick(tic_machine* machine) lua_getglobal(lua, TicFunc); if(lua_isfunction(lua, -1)) { - if(lua_pcall(lua, 0, 0, 0) != LUA_OK) + if(lua_pcall(lua, 0, 0, 0) != LUA_OK) machine->data->error(machine->data->data, lua_tostring(lua, -1)); } else diff --git a/src/run.c b/src/run.c index 2565d75..ca847a4 100644 --- a/src/run.c +++ b/src/run.c @@ -178,6 +178,16 @@ static void preseed() #endif } +static void poll(void* data) +{ + Run* run = (Run*)data; + + while(pollEvent()); + + if (getStudioMode() != TIC_RUN_MODE) + run->tickData.forceExit = true; +} + void initRun(Run* run, Console* console, tic_mem* tic) { *run = (Run) @@ -197,6 +207,8 @@ void initRun(Run* run, Console* console, tic_mem* tic) .data = run, .exit = onExit, .preprocessor = processDoFile, + .hook = poll, + .forceExit = false, }, }; diff --git a/src/ticapi.h b/src/ticapi.h index 3c61988..bb35833 100644 --- a/src/ticapi.h +++ b/src/ticapi.h @@ -45,16 +45,19 @@ typedef struct typedef void(*TraceOutput)(void*, const char*, u8 color); typedef void(*ErrorOutput)(void*, const char*); typedef void(*ExitCallback)(void*); +typedef void(*HookCallback)(void*); typedef struct { TraceOutput trace; ErrorOutput error; ExitCallback exit; + HookCallback hook; u64 (*counter)(); u64 (*freq)(); u64 start; + bool forceExit; void (*preprocessor)(void* data, char* dst);