Skip to content

Commit

Permalink
Merge pull request #348 from spelunky-fyi/Infinity
Browse files Browse the repository at this point in the history
Fix infinite loop detection again
  • Loading branch information
Dregu authored Oct 16, 2023
2 parents ddd0827 + 4ebebeb commit a942c1f
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/game_api/script/lua_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,9 @@ bool LuaBackend::process_vanilla_render_callbacks(ON event)
if (!get_enabled())
return skip;

// used in infinite loop detection to see if game is hanging because a script is hanging
frame_counter++;

auto now = get_frame_count();
VanillaRenderContext render_ctx;
for (auto& [id, callback] : callbacks)
Expand Down
3 changes: 3 additions & 0 deletions src/game_api/script/lua_backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ class LuaBackend

std::map<IMAGE, ScriptImage*> images;

size_t frame_counter{0};
bool infinite_loop_detection{true};

LuaBackend(SoundManager* sound_manager, LuaConsole* console);
virtual ~LuaBackend();

Expand Down
19 changes: 13 additions & 6 deletions src/game_api/script/lua_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,15 @@ void populate_lua_state(sol::state& lua, SoundManager* sound_manager)
{
auto infinite_loop = [](lua_State* argst, [[maybe_unused]] lua_Debug* argdb)
{
static uint32_t last_frame = 0;
auto state = State::get().ptr();
if (last_frame == state->time_startup)
luaL_error(argst, "Hit Infinite Loop Detection of 1bln instructions");
last_frame = state->time_startup;
static size_t last_frame = 0;
auto backend = LuaBackend::get_calling_backend();
if (last_frame == backend->frame_counter && backend->infinite_loop_detection)
luaL_error(argst, "Hit Infinite Loop Detection of 420 million instructions");
last_frame = backend->frame_counter;
};

lua_sethook(lua.lua_state(), NULL, 0, 0);
lua_sethook(lua.lua_state(), infinite_loop, LUA_MASKCOUNT, 500000000);
lua_sethook(lua.lua_state(), infinite_loop, LUA_MASKCOUNT, 420000000);

lua.safe_script(R"(
-- This function walks up the stack until it finds an _ENV that is not _G
Expand Down Expand Up @@ -2160,6 +2160,13 @@ end
return inputs;
};

/// Disable the Infinite Loop Detection of 420 million instructions per frame, if you know what you're doing and need to perform some serious calculations that hang the game updates for several seconds.
lua["set_infinite_loop_detection_enabled"] = [](bool enable)
{
auto backend = LuaBackend::get_calling_backend();
backend->infinite_loop_detection = enable;
};

lua.create_named_table("INPUTS", "NONE", 0, "JUMP", 1, "WHIP", 2, "BOMB", 4, "ROPE", 8, "RUN", 16, "DOOR", 32, "MENU", 64, "JOURNAL", 128, "LEFT", 256, "RIGHT", 512, "UP", 1024, "DOWN", 2048);

lua.create_named_table(
Expand Down

0 comments on commit a942c1f

Please sign in to comment.