From 81fb9a26b2ce2335c8d329d264443386e1d6b553 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 22 Jul 2023 09:55:49 +0200 Subject: [PATCH] - backend update from Raze. * add QualifiedName to VMFunction and allocate these static names from the class data memory arena instead of using FStrings. * null pointer type checks in the VM added to avoid crash on bad codegen. --- src/common/cutscenes/screenjob.cpp | 4 +-- src/common/engine/serializer.cpp | 30 +++++++++++++++++++ src/common/engine/serializer.h | 1 + src/common/scripting/backend/codegen.cpp | 4 +-- src/common/scripting/backend/codegen.h | 4 +-- src/common/scripting/backend/vmbuilder.cpp | 6 ++-- src/common/scripting/core/imports.cpp | 3 +- src/common/scripting/core/scopebarrier.cpp | 2 +- src/common/scripting/core/vmdisasm.cpp | 2 +- src/common/scripting/frontend/zcc_compile.cpp | 2 +- src/common/scripting/jit/jit.cpp | 8 ++--- src/common/scripting/jit/jit_call.cpp | 4 +-- src/common/scripting/jit/jit_runtime.cpp | 2 +- src/common/scripting/vm/vm.h | 3 +- src/common/scripting/vm/vmexec.h | 4 +-- src/common/scripting/vm/vmframe.cpp | 10 +++---- src/common/utility/memarena.cpp | 7 +++++ src/common/utility/memarena.h | 1 + src/common/utility/vectors.h | 8 +---- src/gamedata/d_dehacked.cpp | 2 +- src/gamedata/info.cpp | 6 ++-- src/playsim/p_actionfunctions.cpp | 2 +- src/playsim/p_pspr.cpp | 2 +- src/r_data/models.cpp | 3 +- src/scripting/backend/codegen_doom.cpp | 2 +- 25 files changed, 78 insertions(+), 44 deletions(-) diff --git a/src/common/cutscenes/screenjob.cpp b/src/common/cutscenes/screenjob.cpp index 97bc768627..c227459566 100644 --- a/src/common/cutscenes/screenjob.cpp +++ b/src/common/cutscenes/screenjob.cpp @@ -87,8 +87,8 @@ VMFunction* LookupFunction(const char* qname, bool validate) size_t p = strcspn(qname, "."); if (p == 0) I_Error("Call to undefined function %s", qname); - FString clsname(qname, p); - FString funcname = qname + p + 1; + FName clsname(qname, p, true); + FName funcname(qname + p + 1, true); auto func = PClass::FindFunction(clsname, funcname); if (func == nullptr) diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 8c68b5a3b7..ec84a5fee3 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -55,6 +55,7 @@ #include "textures.h" #include "texturemanager.h" #include "base64.h" +#include "vm.h" extern DObject *WP_NOCHANGE; bool save_full = false; // for testing. Should be removed afterward. @@ -1565,6 +1566,35 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary } } +template<> FSerializer& Serialize(FSerializer& arc, const char* key, VMFunction*& func, VMFunction**) +{ + if (arc.isWriting()) + { + arc.WriteKey(key); + if (func) arc.w->String(func->QualifiedName); + else arc.w->Null(); + } + else + { + func = nullptr; + + auto val = arc.r->FindKey(key); + if (val != nullptr && val->IsString()) + { + auto qname = val->GetString(); + size_t p = strcspn(qname, "."); + if (p != 0) + { + FName clsname(qname, p, true); + FName funcname(qname + p + 1, true); + func = PClass::FindFunction(clsname, funcname); + } + } + + } + return arc; +} + //========================================================================== // // Handler to retrieve a numeric value of any kind. diff --git a/src/common/engine/serializer.h b/src/common/engine/serializer.h index 93c7ef5a1a..c9cc26320f 100644 --- a/src/common/engine/serializer.h +++ b/src/common/engine/serializer.h @@ -310,6 +310,7 @@ inline FSerializer& Serialize(FSerializer& arc, const char* key, BitArray& value template<> FSerializer& Serialize(FSerializer& arc, const char* key, PClass*& clst, PClass** def); template<> FSerializer& Serialize(FSerializer& arc, const char* key, FFont*& font, FFont** def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **def); +template<> FSerializer& Serialize(FSerializer& arc, const char* key, VMFunction*& dict, VMFunction** def); inline FSerializer &Serialize(FSerializer &arc, const char *key, DVector3 &p, DVector3 *def) { diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 2659eda268..2fcbef477d 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -8858,7 +8858,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) } } - if (Self->ValueType->isRealPointer()) + if (Self->ValueType->isRealPointer() && Self->ValueType->toPointer()->PointedType) { auto ptype = Self->ValueType->toPointer()->PointedType; cls = ptype->toContainer(); @@ -9151,7 +9151,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) // [Player701] Catch attempts to call abstract functions directly at compile time if (NoVirtual && Function->Variants[0].Implementation->VarFlags & VARF_Abstract) { - ScriptPosition.Message(MSG_ERROR, "Cannot call abstract function %s", Function->Variants[0].Implementation->PrintableName.GetChars()); + ScriptPosition.Message(MSG_ERROR, "Cannot call abstract function %s", Function->Variants[0].Implementation->PrintableName); delete this; return nullptr; } diff --git a/src/common/scripting/backend/codegen.h b/src/common/scripting/backend/codegen.h index c12e33d3f3..2781adbe5a 100644 --- a/src/common/scripting/backend/codegen.h +++ b/src/common/scripting/backend/codegen.h @@ -348,8 +348,8 @@ public: bool IsQuaternion() const { return ValueType == TypeQuaternion || ValueType == TypeFQuaternion || ValueType == TypeQuaternionStruct; }; bool IsBoolCompat() const { return ValueType->isScalar(); } bool IsObject() const { return ValueType->isObjectPointer(); } - bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType->isArray()); } - bool isStaticArray() const { return (ValueType->isPointer() && ValueType->toPointer()->PointedType->isStaticArray()); } // can only exist in pointer form. + bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType && ValueType->toPointer()->PointedType->isArray()); } + bool isStaticArray() const { return (ValueType->isPointer() && ValueType->toPointer()->PointedType && ValueType->toPointer()->PointedType->isStaticArray()); } // can only exist in pointer form. bool IsDynamicArray() const { return (ValueType->isDynArray()); } bool IsMap() const { return ValueType->isMap(); } bool IsMapIterator() const { return ValueType->isMapIterator(); } diff --git a/src/common/scripting/backend/vmbuilder.cpp b/src/common/scripting/backend/vmbuilder.cpp index 7d270af61e..c576eae4b5 100644 --- a/src/common/scripting/backend/vmbuilder.cpp +++ b/src/common/scripting/backend/vmbuilder.cpp @@ -790,7 +790,7 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo it.PrintableName = name; it.Function = new VMScriptFunction; it.Function->Name = functype->SymbolName; - it.Function->PrintableName = name; + it.Function->QualifiedName = it.Function->PrintableName = ClassDataAllocator.Strdup(name); it.Function->ImplicitArgs = functype->GetImplicitArgs(); it.Proto = nullptr; it.FromDecorate = fromdecorate; @@ -866,7 +866,7 @@ void FFunctionBuildList::Build() item.Proto = ctx.ReturnProto; if (item.Proto == nullptr) { - item.Code->ScriptPosition.Message(MSG_ERROR, "Function %s without prototype", item.PrintableName.GetChars()); + item.Code->ScriptPosition.Message(MSG_ERROR, "Function %s without prototype", item.PrintableName); continue; } @@ -913,7 +913,7 @@ void FFunctionBuildList::Build() catch (CRecoverableError &err) { // catch errors from the code generator and pring something meaningful. - item.Code->ScriptPosition.Message(MSG_ERROR, "%s in %s", err.GetMessage(), item.PrintableName.GetChars()); + item.Code->ScriptPosition.Message(MSG_ERROR, "%s in %s", err.GetMessage(), item.PrintableName); } } delete item.Code; diff --git a/src/common/scripting/core/imports.cpp b/src/common/scripting/core/imports.cpp index c5a8cf9c5e..3006462cd8 100644 --- a/src/common/scripting/core/imports.cpp +++ b/src/common/scripting/core/imports.cpp @@ -198,7 +198,8 @@ void InitImports() { assert(afunc->VMPointer != NULL); *(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName); - (*(afunc->VMPointer))->PrintableName.Format("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName); + (*(afunc->VMPointer))->QualifiedName = ClassDataAllocator.Strdup(FStringf("%s.%s", afunc->ClassName + 1, afunc->FuncName)); + (*(afunc->VMPointer))->PrintableName = ClassDataAllocator.Strdup(FStringf("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName)); (*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative; AFTable.Push(*afunc); }); diff --git a/src/common/scripting/core/scopebarrier.cpp b/src/common/scripting/core/scopebarrier.cpp index a6c5a23705..8e03f757fe 100644 --- a/src/common/scripting/core/scopebarrier.cpp +++ b/src/common/scripting/core/scopebarrier.cpp @@ -221,5 +221,5 @@ void FScopeBarrier::ValidateCall(PClass* selftype, VMFunction *calledfunc, int o { int innerside = FScopeBarrier::SideFromObjectFlags(selftype->VMType->ScopeFlags); if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData)) - ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->PrintableName.GetChars(), FScopeBarrier::StringFromSide(outerside)); + ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->PrintableName, FScopeBarrier::StringFromSide(outerside)); } \ No newline at end of file diff --git a/src/common/scripting/core/vmdisasm.cpp b/src/common/scripting/core/vmdisasm.cpp index 433a2fd1ab..86d566985b 100644 --- a/src/common/scripting/core/vmdisasm.cpp +++ b/src/common/scripting/core/vmdisasm.cpp @@ -528,7 +528,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction } else if (code[i].op == OP_CALL_K && callfunc) { - printf_wrapper(out, " [%s]\n", callfunc->PrintableName.GetChars()); + printf_wrapper(out, " [%s]\n", callfunc->PrintableName); } else { diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index ffba4c301d..fb21526f1d 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -2798,7 +2798,7 @@ void ZCCCompiler::InitFunctions() { if (v->VarFlags & VARF_Abstract) { - Error(c->cls, "Non-abstract class %s must override abstract function %s", c->Type()->TypeName.GetChars(), v->PrintableName.GetChars()); + Error(c->cls, "Non-abstract class %s must override abstract function %s", c->Type()->TypeName.GetChars(), v->PrintableName); } } } diff --git a/src/common/scripting/jit/jit.cpp b/src/common/scripting/jit/jit.cpp index 13679d59aa..27b69cac47 100644 --- a/src/common/scripting/jit/jit.cpp +++ b/src/common/scripting/jit/jit.cpp @@ -15,7 +15,7 @@ static void OutputJitLog(const asmjit::StringLogger &logger); JitFuncPtr JitCompile(VMScriptFunction *sfunc) { #if 0 - if (strcmp(sfunc->PrintableName.GetChars(), "StatusScreen.drawNum") != 0) + if (strcmp(sfunc->PrintableName, "StatusScreen.drawNum") != 0) return nullptr; #endif @@ -35,7 +35,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc) catch (const CRecoverableError &e) { OutputJitLog(logger); - Printf("%s: Unexpected JIT error: %s\n",sfunc->PrintableName.GetChars(), e.what()); + Printf("%s: Unexpected JIT error: %s\n",sfunc->PrintableName, e.what()); return nullptr; } } @@ -237,7 +237,7 @@ void JitCompiler::Setup() cc.comment(marks, 56); FString funcname; - funcname.Format("Function: %s", sfunc->PrintableName.GetChars()); + funcname.Format("Function: %s", sfunc->PrintableName); cc.comment(funcname.GetChars(), funcname.Len()); cc.comment(marks, 56); @@ -364,7 +364,7 @@ void JitCompiler::SetupSimpleFrame() if (errorDetails) { - I_FatalError("JIT: inconsistent number of %s for function %s", errorDetails, sfunc->PrintableName.GetChars()); + I_FatalError("JIT: inconsistent number of %s for function %s", errorDetails, sfunc->PrintableName); } for (int i = regd; i < sfunc->NumRegD; i++) diff --git a/src/common/scripting/jit/jit_call.cpp b/src/common/scripting/jit/jit_call.cpp index e6c1feb0b6..d7074edc9d 100644 --- a/src/common/scripting/jit/jit_call.cpp +++ b/src/common/scripting/jit/jit_call.cpp @@ -97,7 +97,7 @@ void JitCompiler::EmitVMCall(asmjit::X86Gp vmfunc, VMFunction *target) call->setArg(2, Imm(B)); call->setArg(3, GetCallReturns()); call->setArg(4, Imm(C)); - call->setInlineComment(target ? target->PrintableName.GetChars() : "VMCall"); + call->setInlineComment(target ? target->PrintableName : "VMCall"); LoadInOuts(); LoadReturns(pc + 1, C); @@ -360,7 +360,7 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target) asmjit::CBNode *cursorBefore = cc.getCursor(); auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature()); - call->setInlineComment(target->PrintableName.GetChars()); + call->setInlineComment(target->PrintableName); asmjit::CBNode *cursorAfter = cc.getCursor(); cc.setCursor(cursorBefore); diff --git a/src/common/scripting/jit/jit_runtime.cpp b/src/common/scripting/jit/jit_runtime.cpp index 89672b9405..cdfbedb674 100644 --- a/src/common/scripting/jit/jit_runtime.cpp +++ b/src/common/scripting/jit/jit_runtime.cpp @@ -306,7 +306,7 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler) if (result == 0) I_Error("RtlAddFunctionTable failed"); - JitDebugInfo.Push({ compiler->GetScriptFunction()->PrintableName, compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr }); + JitDebugInfo.Push({ FString(compiler->GetScriptFunction()->PrintableName), compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr }); #endif return p; diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 9529cf5c08..4b9334c048 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -451,7 +451,8 @@ public: FName Name; const uint8_t *RegTypes = nullptr; TArray DefaultArgs; - FString PrintableName; // so that the VM can print meaningful info if something in this function goes wrong. + const char* QualifiedName = nullptr; + const char* PrintableName = nullptr; // same as QualifiedName, but can have additional annotations. class PPrototype *Proto; TArray ArgFlags; // Should be the same length as Proto->ArgumentTypes diff --git a/src/common/scripting/vm/vmexec.h b/src/common/scripting/vm/vmexec.h index f303304b81..5ddac8bd45 100644 --- a/src/common/scripting/vm/vmexec.h +++ b/src/common/scripting/vm/vmexec.h @@ -895,7 +895,7 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) catch (CVMAbortException &err) { err.MaybePrintMessage(); - err.stacktrace.AppendFormat("Called from %s\n", call->PrintableName.GetChars()); + err.stacktrace.AppendFormat("Called from %s\n", call->PrintableName); // PrintParameters(reg.param + f->NumParam - B, B); throw; } @@ -2000,7 +2000,7 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) catch (CVMAbortException &err) { err.MaybePrintMessage(); - err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName.GetChars(), sfunc->SourceFileName.GetChars(), sfunc->PCToLine(pc)); + err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName, sfunc->SourceFileName.GetChars(), sfunc->PCToLine(pc)); // PrintParameters(reg.param + f->NumParam - B, B); throw; } diff --git a/src/common/scripting/vm/vmframe.cpp b/src/common/scripting/vm/vmframe.cpp index a2c972820b..a13829ddad 100644 --- a/src/common/scripting/vm/vmframe.cpp +++ b/src/common/scripting/vm/vmframe.cpp @@ -80,7 +80,7 @@ void VMFunction::CreateRegUse() if (!Proto) { //if (RegTypes) return; - //Printf(TEXTCOLOR_ORANGE "Function without prototype needs register info manually set: %s\n", PrintableName.GetChars()); + //Printf(TEXTCOLOR_ORANGE "Function without prototype needs register info manually set: %s\n", PrintableName); return; } assert(Proto->isPrototype()); @@ -277,7 +277,7 @@ static bool CanJit(VMScriptFunction *func) if (func->NumRegA + func->NumRegD + func->NumRegF + func->NumRegS < maxregs) return true; - Printf(TEXTCOLOR_ORANGE "%s is using too many registers (%d of max %d)! Function will not use native code.\n", func->PrintableName.GetChars(), func->NumRegA + func->NumRegD + func->NumRegF + func->NumRegS, maxregs); + Printf(TEXTCOLOR_ORANGE "%s is using too many registers (%d of max %d)! Function will not use native code.\n", func->PrintableName, func->NumRegA + func->NumRegD + func->NumRegF + func->NumRegS, maxregs); return false; } @@ -289,7 +289,7 @@ int VMScriptFunction::FirstScriptCall(VMFunction *func, VMValue *params, int num // rather than let GZDoom crash. if (func->VarFlags & VARF_Abstract) { - ThrowAbortException(X_OTHER, "attempt to call abstract function %s.", func->PrintableName.GetChars()); + ThrowAbortException(X_OTHER, "attempt to call abstract function %s.", func->PrintableName); } #ifdef HAVE_VM_JIT if (vm_jit && CanJit(static_cast(func))) @@ -320,7 +320,7 @@ int VMNativeFunction::NativeScriptCall(VMFunction *func, VMValue *params, int nu catch (CVMAbortException &err) { err.MaybePrintMessage(); - err.stacktrace.AppendFormat("Called from %s\n", func->PrintableName.GetChars()); + err.stacktrace.AppendFormat("Called from %s\n", func->PrintableName); throw; } } @@ -702,7 +702,7 @@ void CVMAbortException::MaybePrintMessage() CVMAbortException err(reason, moreinfo, ap); - err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName.GetChars(), sfunc->SourceFileName.GetChars(), sfunc->PCToLine(line)); + err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName, sfunc->SourceFileName.GetChars(), sfunc->PCToLine(line)); throw err; } diff --git a/src/common/utility/memarena.cpp b/src/common/utility/memarena.cpp index 2a9467dc21..767824a649 100644 --- a/src/common/utility/memarena.cpp +++ b/src/common/utility/memarena.cpp @@ -132,6 +132,13 @@ void* FMemArena::Calloc(size_t size) return mem; } +const char* FMemArena::Strdup(const char* str) +{ + char* p = (char*)Alloc(strlen(str) + 1); + strcpy(p, str); + return p; +} + //========================================================================== // // FMemArena :: FreeAll diff --git a/src/common/utility/memarena.h b/src/common/utility/memarena.h index bb7f60b9a5..8c1def64dc 100644 --- a/src/common/utility/memarena.h +++ b/src/common/utility/memarena.h @@ -45,6 +45,7 @@ public: void *Alloc(size_t size); void* Calloc(size_t size); + const char* Strdup(const char*); void FreeAll(); void FreeAllBlocks(); FString DumpInfo(); diff --git a/src/common/utility/vectors.h b/src/common/utility/vectors.h index ea5cb5250c..6b82cc5cbc 100644 --- a/src/common/utility/vectors.h +++ b/src/common/utility/vectors.h @@ -55,7 +55,7 @@ namespace pi inline constexpr float pif() { return 3.14159265358979323846f; } } -// optionally use reliable math routines if reproducability across hardware is important., but let this still compile without them. +// optionally use reliable math routines if reproducability across hardware is important, but let this still compile without them. #if __has_include("math/cmath.h") #include "math/cmath.h" #else @@ -1506,12 +1506,6 @@ inline TAngle absangle(const TAngle &a1, const TAngle &a2) return fabs(deltaangle(a2, a1)); } -template -inline TAngle clamp(const TAngle &angle, const TAngle &min, const TAngle &max) -{ - return TAngle::fromDeg(clamp(angle.Degrees(), min.Degrees(), max.Degrees())); -} - inline TAngle VecToAngle(double x, double y) { return TAngle::fromRad(g_atan2(y, x)); diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 442068a679..96925365c9 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1016,7 +1016,7 @@ static void SetDehParams(FState *state, int codepointer, VMDisassemblyDumper &di sfunc->NumArgs = numargs; sfunc->ImplicitArgs = numargs; state->SetAction(sfunc); - sfunc->PrintableName.Format("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2); + sfunc->PrintableName = ClassDataAllocator.Strdup(FStringf("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2)); disasmdump.Write(sfunc, sfunc->PrintableName); diff --git a/src/gamedata/info.cpp b/src/gamedata/info.cpp index 3736cb4d2e..2e0109db49 100644 --- a/src/gamedata/info.cpp +++ b/src/gamedata/info.cpp @@ -132,16 +132,16 @@ void FState::CheckCallerType(AActor *self, AActor *stateowner) // This should really never happen. Any valid action function must have actor pointers here. if (!requiredType->isObjectPointer()) { - ThrowAbortException(X_OTHER, "Bad function prototype in function call to %s", ActionFunc->PrintableName.GetChars()); + ThrowAbortException(X_OTHER, "Bad function prototype in function call to %s", ActionFunc->PrintableName); } auto cls = static_cast(requiredType)->PointedClass(); if (check == nullptr) { - ThrowAbortException(X_OTHER, "%s called without valid caller. %s expected", ActionFunc->PrintableName.GetChars(), cls->TypeName.GetChars()); + ThrowAbortException(X_OTHER, "%s called without valid caller. %s expected", ActionFunc->PrintableName, cls->TypeName.GetChars()); } if (!(StateFlags & STF_DEHACKED) && !check->IsKindOf(cls)) { - ThrowAbortException(X_OTHER, "Invalid class %s in function call to %s. %s expected", check->GetClass()->TypeName.GetChars(), ActionFunc->PrintableName.GetChars(), cls->TypeName.GetChars()); + ThrowAbortException(X_OTHER, "Invalid class %s in function call to %s. %s expected", check->GetClass()->TypeName.GetChars(), ActionFunc->PrintableName, cls->TypeName.GetChars()); } }; diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 2d9e488a1b..b4768cae0d 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -129,7 +129,7 @@ static int CallStateChain (AActor *self, AActor *actor, FState *state) // If an unsafe function (i.e. one that accesses user variables) is being detected, print a warning once and remove the bogus function. We may not call it because that would inevitably crash. auto owner = FState::StaticFindStateOwner(state); Printf(TEXTCOLOR_RED "Unsafe state call in state %s to %s which accesses user variables. The action function has been removed from this state\n", - FState::StaticGetStateName(state).GetChars(), state->ActionFunc->PrintableName.GetChars()); + FState::StaticGetStateName(state).GetChars(), state->ActionFunc->PrintableName); state->ActionFunc = nullptr; } diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index b32ce67e66..ce2cdfab12 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -556,7 +556,7 @@ void DPSprite::SetState(FState *newstate, bool pending) { // If an unsafe function (i.e. one that accesses user variables) is being detected, print a warning once and remove the bogus function. We may not call it because that would inevitably crash. Printf(TEXTCOLOR_RED "Unsafe state call in state %sd to %s which accesses user variables. The action function has been removed from this state\n", - FState::StaticGetStateName(newstate).GetChars(), newstate->ActionFunc->PrintableName.GetChars()); + FState::StaticGetStateName(newstate).GetChars(), newstate->ActionFunc->PrintableName); newstate->ActionFunc = nullptr; } if (newstate->CallAction(Owner->mo, Caller, &stp, &nextstate)) diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index ad9c9978a9..ab632b34f8 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -351,8 +351,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr //modelFrame if (actor->modelData->modelFrameGenerators.Size() > i - && actor->modelData->modelFrameGenerators[i] >= 0 - && actor->modelData->modelFrameGenerators[i] < modelsamount + && (unsigned)actor->modelData->modelFrameGenerators[i] < modelsamount && smf->modelframes[actor->modelData->modelFrameGenerators[i]] >= 0 ) { modelframe = smf->modelframes[actor->modelData->modelFrameGenerators[i]]; diff --git a/src/scripting/backend/codegen_doom.cpp b/src/scripting/backend/codegen_doom.cpp index 1d008446ce..9f2b37e849 100644 --- a/src/scripting/backend/codegen_doom.cpp +++ b/src/scripting/backend/codegen_doom.cpp @@ -309,7 +309,7 @@ static bool UnravelVarArgAJump(FxVMFunctionCall *func, FCompileContext &ctx) static bool AJumpProcessing(FxVMFunctionCall *func, FCompileContext &ctx) { // Unfortunately the PrintableName is the only safe thing to catch this special case here. - if (func->Function->Variants[0].Implementation->PrintableName.CompareNoCase("Actor.A_Jump [Native]") == 0) + if (stricmp(func->Function->Variants[0].Implementation->QualifiedName, "Actor.A_Jump") == 0) { // Unravel the varargs part of this function here so that the VM->native interface does not have to deal with it anymore. if (func->ArgList.Size() > 2)