mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 15:32:54 +00:00
- implicitly clear local dynamic arrays
https://forum.zdoom.org/viewtopic.php?t=62710
This commit is contained in:
parent
1dd08a73ed
commit
ce8b235d0b
2 changed files with 30 additions and 15 deletions
|
@ -11272,6 +11272,7 @@ FxLocalVariableDeclaration::FxLocalVariableDeclaration(PType *type, FName name,
|
||||||
Name = name;
|
Name = name;
|
||||||
RegCount = type == TypeVector2 ? 2 : type == TypeVector3 ? 3 : 1;
|
RegCount = type == TypeVector2 ? 2 : type == TypeVector3 ? 3 : 1;
|
||||||
Init = initval;
|
Init = initval;
|
||||||
|
clearExpr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FxLocalVariableDeclaration::~FxLocalVariableDeclaration()
|
FxLocalVariableDeclaration::~FxLocalVariableDeclaration()
|
||||||
|
@ -11282,6 +11283,15 @@ FxLocalVariableDeclaration::~FxLocalVariableDeclaration()
|
||||||
FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx)
|
FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
CHECKRESOLVED();
|
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)
|
if (ctx.Block == nullptr)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Variable declaration outside compound statement");
|
ScriptPosition.Message(MSG_ERROR, "Variable declaration outside compound statement");
|
||||||
|
@ -11476,6 +11486,10 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
|
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
|
||||||
}
|
}
|
||||||
|
else if (ValueType->isDynArray())
|
||||||
|
{
|
||||||
|
ClearDynamicArray(build);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ExpEmit();
|
return ExpEmit();
|
||||||
}
|
}
|
||||||
|
@ -11507,6 +11521,11 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
|
||||||
// For that all local stack variables need to live for the entire execution of a function.
|
// 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)
|
FxStaticArray::FxStaticArray(PType *type, FName name, FArgumentList &args, const FScriptPosition &pos)
|
||||||
: FxLocalVariableDeclaration(NewArray(type, args.Size()), name, nullptr, VARF_Static|VARF_ReadOnly, pos)
|
: FxLocalVariableDeclaration(NewArray(type, args.Size()), name, nullptr, VARF_Static|VARF_ReadOnly, pos)
|
||||||
|
@ -11591,7 +11610,6 @@ FxLocalArrayDeclaration::FxLocalArrayDeclaration(PType *type, FName name, FArgum
|
||||||
{
|
{
|
||||||
ExprType = EFX_LocalArrayDeclaration;
|
ExprType = EFX_LocalArrayDeclaration;
|
||||||
values = std::move(args);
|
values = std::move(args);
|
||||||
clearExpr = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
||||||
|
@ -11607,16 +11625,6 @@ FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
||||||
auto elementType = (static_cast<PArray *> (ValueType))->ElementType;
|
auto elementType = (static_cast<PArray *> (ValueType))->ElementType;
|
||||||
auto elementCount = (static_cast<PArray *> (ValueType))->ElementCount;
|
auto elementCount = (static_cast<PArray *> (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)
|
if (values.Size() > elementCount)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Initializer contains more elements than the array can contain");
|
ScriptPosition.Message(MSG_ERROR, "Initializer contains more elements than the array can contain");
|
||||||
|
@ -11673,9 +11681,11 @@ ExpEmit FxLocalArrayDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
assert(!(VarFlags & VARF_Out)); // 'out' variables should never be initialized, they can only exist as function parameters.
|
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<PArray *>(ValueType)->ElementSize);
|
auto elementSizeConst = build->GetConstantInt(static_cast<PArray *>(ValueType)->ElementSize);
|
||||||
|
@ -11686,7 +11696,7 @@ ExpEmit FxLocalArrayDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
ExpEmit emitval = v->Emit(build);
|
ExpEmit emitval = v->Emit(build);
|
||||||
|
|
||||||
if (IsDynamicArray())
|
if (isDynamicArray)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2131,6 +2131,12 @@ class FxLocalVariableDeclaration : public FxExpression
|
||||||
FxExpression *Init;
|
FxExpression *Init;
|
||||||
int VarFlags;
|
int VarFlags;
|
||||||
int RegCount;
|
int RegCount;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FxExpression *clearExpr;
|
||||||
|
|
||||||
|
void ClearDynamicArray(VMFunctionBuilder *build);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int StackOffset = -1;
|
int StackOffset = -1;
|
||||||
int RegNum = -1;
|
int RegNum = -1;
|
||||||
|
@ -2194,7 +2200,6 @@ class FxLocalArrayDeclaration : public FxLocalVariableDeclaration
|
||||||
{
|
{
|
||||||
PType *ElementType;
|
PType *ElementType;
|
||||||
FArgumentList values;
|
FArgumentList values;
|
||||||
FxExpression *clearExpr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue