From 9aff83cfdc117610e5203f74f7641808927256cf Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 20 Oct 2019 12:59:20 +0300 Subject: [PATCH] - implicitly clear local dynamic arrays https://forum.zdoom.org/viewtopic.php?t=62710 --- src/scripting/backend/codegen.cpp | 38 +++++++++++++++++++------------ src/scripting/backend/codegen.h | 7 +++++- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 004764b3d..360b7c4f3 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -11276,6 +11276,7 @@ FxLocalVariableDeclaration::FxLocalVariableDeclaration(PType *type, FName name, Name = name; RegCount = type == TypeVector2 ? 2 : type == TypeVector3 ? 3 : 1; Init = initval; + clearExpr = nullptr; } FxLocalVariableDeclaration::~FxLocalVariableDeclaration() @@ -11286,6 +11287,15 @@ FxLocalVariableDeclaration::~FxLocalVariableDeclaration() FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); + + if (IsDynamicArray()) + { + auto stackVar = new FxStackVariable(ValueType, StackOffset, ScriptPosition); + FArgumentList argsList; + clearExpr = new FxMemberFunctionCall(stackVar, "Clear", argsList, ScriptPosition); + SAFE_RESOLVE(clearExpr, ctx); + } + if (ctx.Block == nullptr) { ScriptPosition.Message(MSG_ERROR, "Variable declaration outside compound statement"); @@ -11480,6 +11490,10 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build) } if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this); } + else if (ValueType->isDynArray()) + { + ClearDynamicArray(build); + } } return ExpEmit(); } @@ -11511,6 +11525,11 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build) // For that all local stack variables need to live for the entire execution of a function. } +void FxLocalVariableDeclaration::ClearDynamicArray(VMFunctionBuilder *build) +{ + assert(clearExpr != nullptr); + clearExpr->Emit(build); +} FxStaticArray::FxStaticArray(PType *type, FName name, FArgumentList &args, const FScriptPosition &pos) : FxLocalVariableDeclaration(NewArray(type, args.Size()), name, nullptr, VARF_Static|VARF_ReadOnly, pos) @@ -11595,7 +11614,6 @@ FxLocalArrayDeclaration::FxLocalArrayDeclaration(PType *type, FName name, FArgum { ExprType = EFX_LocalArrayDeclaration; values = std::move(args); - clearExpr = nullptr; } FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx) @@ -11611,16 +11629,6 @@ FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx) auto elementType = (static_cast (ValueType))->ElementType; auto elementCount = (static_cast (ValueType))->ElementCount; - // We HAVE to clear dynamic arrays before initializing them - if (IsDynamicArray()) - { - FArgumentList argsList; - argsList.Clear(); - - clearExpr = new FxMemberFunctionCall(stackVar, "Clear", argsList, (const FScriptPosition) ScriptPosition); - SAFE_RESOLVE(clearExpr, ctx); - } - if (values.Size() > elementCount) { ScriptPosition.Message(MSG_ERROR, "Initializer contains more elements than the array can contain"); @@ -11677,9 +11685,11 @@ ExpEmit FxLocalArrayDeclaration::Emit(VMFunctionBuilder *build) { assert(!(VarFlags & VARF_Out)); // 'out' variables should never be initialized, they can only exist as function parameters. - if (IsDynamicArray() && clearExpr != nullptr) + const bool isDynamicArray = IsDynamicArray(); + + if (isDynamicArray) { - clearExpr->Emit(build); + ClearDynamicArray(build); } auto elementSizeConst = build->GetConstantInt(static_cast(ValueType)->ElementSize); @@ -11690,7 +11700,7 @@ ExpEmit FxLocalArrayDeclaration::Emit(VMFunctionBuilder *build) { ExpEmit emitval = v->Emit(build); - if (IsDynamicArray()) + if (isDynamicArray) { continue; } diff --git a/src/scripting/backend/codegen.h b/src/scripting/backend/codegen.h index aa05c7d06..26f2011b2 100644 --- a/src/scripting/backend/codegen.h +++ b/src/scripting/backend/codegen.h @@ -2131,6 +2131,12 @@ class FxLocalVariableDeclaration : public FxExpression FxExpression *Init; int VarFlags; int RegCount; + +protected: + FxExpression *clearExpr; + + void ClearDynamicArray(VMFunctionBuilder *build); + public: int StackOffset = -1; int RegNum = -1; @@ -2194,7 +2200,6 @@ class FxLocalArrayDeclaration : public FxLocalVariableDeclaration { PType *ElementType; FArgumentList values; - FxExpression *clearExpr; public: