diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index b8ba618901..2e309514ca 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -739,7 +739,7 @@ static void (*MBFCodePointerFactories[])(FunctionCallEmitter&, int, int) = // Creates new functions for the given state so as to convert MBF-args (misc1 and misc2) into real args. -void SetDehParams(FState *state, int codepointer) +static void SetDehParams(FState *state, int codepointer, VMDisassemblyDumper &disasmdump) { static const uint8_t regts[] = { REGT_POINTER, REGT_POINTER, REGT_POINTER }; int value1 = state->GetMisc1(); @@ -795,15 +795,8 @@ void SetDehParams(FState *state, int codepointer) state->SetAction(sfunc); sfunc->PrintableName.Format("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2); - if (Args->CheckParm("-dumpdisasm")) - { - FILE *dump = fopen("disasm.txt", "a"); - if (dump != nullptr) - { - DumpFunction(dump, sfunc, sfunc->PrintableName.GetChars(), (int)sfunc->PrintableName.Len()); - } - fclose(dump); - } + disasmdump.Write(sfunc, sfunc->PrintableName); + #ifdef HAVE_VM_JIT if (Args->CheckParm("-dumpjit")) { @@ -2651,10 +2644,12 @@ static void UnloadDehSupp () { if (--DehUseCount <= 0) { + VMDisassemblyDumper disasmdump(VMDisassemblyDumper::Append); + // Handle MBF params here, before the required arrays are cleared for (unsigned int i=0; i < MBFParamStates.Size(); i++) { - SetDehParams(MBFParamStates[i].state, MBFParamStates[i].pointer); + SetDehParams(MBFParamStates[i].state, MBFParamStates[i].pointer, disasmdump); } MBFParamStates.Clear(); MBFParamStates.ShrinkToFit(); diff --git a/src/scripting/backend/vmbuilder.cpp b/src/scripting/backend/vmbuilder.cpp index b787f8b587..8a6800d46b 100644 --- a/src/scripting/backend/vmbuilder.cpp +++ b/src/scripting/backend/vmbuilder.cpp @@ -809,11 +809,7 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo void FFunctionBuildList::Build() { - int codesize = 0; - int datasize = 0; - FILE *dump = nullptr; - - if (Args->CheckParm("-dumpdisasm")) dump = fopen("disasm.txt", "w"); + VMDisassemblyDumper disasmdump(VMDisassemblyDumper::Overwrite); for (auto &item : mItems) { @@ -900,13 +896,8 @@ void FFunctionBuildList::Build() } } - if (dump != nullptr) - { - DumpFunction(dump, sfunc, item.PrintableName.GetChars(), (int)item.PrintableName.Len()); - codesize += sfunc->CodeSize; - datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) + - sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString); - } + disasmdump.Write(sfunc, item.PrintableName); + sfunc->Unsafe = ctx.Unsafe; } catch (CRecoverableError &err) @@ -916,15 +907,7 @@ void FFunctionBuildList::Build() } } delete item.Code; - if (dump != nullptr) - { - fflush(dump); - } - } - if (dump != nullptr) - { - fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes", codesize * 4, datasize); - fclose(dump); + disasmdump.Flush(); } VMFunction::CreateRegUseInfo(); FScriptPosition::StrictErrors = false; @@ -1122,3 +1105,50 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray return retreg; } + +VMDisassemblyDumper::VMDisassemblyDumper(const FileOperationType operation) +{ + static const char *const DUMP_ARG_NAME = "-dumpdisasm"; + + if (Args->CheckParm(DUMP_ARG_NAME)) + { + dump = fopen("disasm.txt", operation == Overwrite ? "w" : "a"); + namefilter = Args->CheckValue(DUMP_ARG_NAME); + namefilter.ToLower(); + } +} + +VMDisassemblyDumper::~VMDisassemblyDumper() +{ + if (dump != nullptr) + { + fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes\n", codesize * 4, datasize); + fclose(dump); + } +} + +void VMDisassemblyDumper::Write(VMScriptFunction *sfunc, const FString &fname) +{ + if (dump != nullptr) + { + if (namefilter.Len() > 0 && fname.MakeLower().IndexOf(namefilter) == -1) + { + return; + } + + assert(sfunc != nullptr); + + DumpFunction(dump, sfunc, fname, (int)fname.Len()); + codesize += sfunc->CodeSize; + datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) + + sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString); + } +} + +void VMDisassemblyDumper::Flush() +{ + if (dump != nullptr) + { + fflush(dump); + } +} diff --git a/src/scripting/backend/vmbuilder.h b/src/scripting/backend/vmbuilder.h index 856e2afca3..8bb43565e6 100644 --- a/src/scripting/backend/vmbuilder.h +++ b/src/scripting/backend/vmbuilder.h @@ -211,4 +211,26 @@ public: } }; +class VMDisassemblyDumper +{ +public: + enum FileOperationType + { + Overwrite, + Append + }; + + explicit VMDisassemblyDumper(const FileOperationType operation); + ~VMDisassemblyDumper(); + + void Write(VMScriptFunction *sfunc, const FString &fname); + void Flush(); + +private: + FILE *dump = nullptr; + FString namefilter; + int codesize = 0; + int datasize = 0; +}; + #endif