From 71294823d1c88f2dd79830dcf646742df0bbe0d1 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 19 May 2024 19:10:55 +0000 Subject: [PATCH] Merge branch 'acs-printkill' into 'master' Add ACS branch limit and implement printKill See merge request KartKrew/RingRacers!22 --- src/acs/environment.cpp | 42 +++++++++++++++++++++++++++++++++++++++++ src/acs/environment.hpp | 2 ++ 2 files changed, 44 insertions(+) diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index 7a4375060..85258f554 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -53,6 +53,9 @@ Environment::Environment() // Not that we're adding any modules to it, though. :p global->active = true; + // Set a branch limit (same as ZDoom's instruction limit) + branchLimit = 2000000; + // Add the data & function pointers. // Starting with raw ACS0 codes. I'm using this classic-style @@ -375,3 +378,42 @@ ACSVM::Word Environment::callSpecImpl P_ProcessSpecial(activator, spec, args, stringargs); return 1; } + +void Environment::printKill(ACSVM::Thread *thread, ACSVM::Word type, ACSVM::Word data) +{ + std::string scriptName; + + ACSVM::String *scriptNamePtr = (thread->script != nullptr) ? (thread->script->name.s) : nullptr; + if (scriptNamePtr && scriptNamePtr->len) + scriptName = std::string(scriptNamePtr->str); + else + scriptName = std::to_string((int)thread->script->name.i); + + ACSVM::KillType killType = static_cast(type); + + if (killType == ACSVM::KillType::BranchLimit) + { + CONS_Alert(CONS_ERROR, "Terminated runaway script %s\n", scriptName.c_str()); + return; + } + else if (killType == ACSVM::KillType::UnknownCode) + { + CONS_Alert(CONS_ERROR, "ACSVM ERROR: Unknown opcode %d in script %s\n", data, scriptName.c_str()); + } + else if (killType == ACSVM::KillType::UnknownFunc) + { + CONS_Alert(CONS_ERROR, "ACSVM ERROR: Unknown function %d in script %s\n", data, scriptName.c_str()); + } + else if (killType == ACSVM::KillType::OutOfBounds) + { + CONS_Alert(CONS_ERROR, "ACSVM ERROR: Jumped to out of bounds location %lu in script %s\n", + (thread->codePtr - thread->module->codeV.data() - 1), scriptName.c_str()); + } + else + { + CONS_Alert(CONS_ERROR, "ACSVM ERROR: Kill %u:%d at %lu in script %s\n", + type, data, (thread->codePtr - thread->module->codeV.data() - 1), scriptName.c_str()); + } + + CONS_Printf("Script terminated.\n"); +} diff --git a/src/acs/environment.hpp b/src/acs/environment.hpp index 88bc0710f..54f714234 100644 --- a/src/acs/environment.hpp +++ b/src/acs/environment.hpp @@ -41,6 +41,8 @@ public: virtual ACSVM::Thread *allocThread(); + virtual void printKill(ACSVM::Thread *thread, ACSVM::Word type, ACSVM::Word data); + protected: virtual void loadModule(ACSVM::Module *module); };