Object destruction on break, continue and return

This commit is contained in:
drmortalwombat 2023-06-21 22:30:28 +02:00
parent 9bcec5bf17
commit 04eeedb0b9
2 changed files with 50 additions and 16 deletions

View File

@ -863,7 +863,7 @@ void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodePro
if (stack->mDestruct) if (stack->mDestruct)
{ {
DestructStack* destack = nullptr; DestructStack* destack = nullptr;
TranslateExpression(procType, proc, block, stack->mDestruct, destack, nullptr, nullptr, nullptr); TranslateExpression(procType, proc, block, stack->mDestruct, destack, BranchTarget(), BranchTarget(), nullptr);
} }
stack = stack->mNext; stack = stack->mNext;
@ -873,7 +873,7 @@ void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodePro
mErrors->Error(proc->mLocation, EWARN_DESTRUCTOR_MISMATCH, "Destructor sequence mismatch"); mErrors->Error(proc->mLocation, EWARN_DESTRUCTOR_MISMATCH, "Destructor sequence mismatch");
} }
InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr) InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr)
{ {
DestructStack* destack = nullptr; DestructStack* destack = nullptr;
@ -1033,7 +1033,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
rdec->mSize = rdec->mBase->mSize; rdec->mSize = rdec->mBase->mSize;
} }
vl = TranslateExpression(ftype, proc, block, fexp, destack, nullptr, nullptr, &nmapper); vl = TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins); block->Append(jins);
@ -1059,7 +1059,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
} }
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, ExValue* lrexp) InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, ExValue* lrexp)
{ {
Declaration* dec; Declaration* dec;
ExValue vl, vr; ExValue vl, vr;
@ -3071,6 +3071,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mCode = IC_RETURN; ins->mCode = IC_RETURN;
} }
UnwindDestructStack(procType, proc, block, destack, nullptr);
if (ins->mCode != IC_NONE) if (ins->mCode != IC_NONE)
block->Append(ins); block->Append(ins);
@ -3089,12 +3091,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_BREAK: case EX_BREAK:
{ {
if (breakBlock) if (breakBlock.mBlock)
{ {
UnwindDestructStack(procType, proc, block, destack, breakBlock.mStack);
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins); block->Append(jins);
block->Close(breakBlock, nullptr); block->Close(breakBlock.mBlock, nullptr);
block = new InterCodeBasicBlock(proc); block = new InterCodeBasicBlock(proc);
} }
else else
@ -3105,12 +3108,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_CONTINUE: case EX_CONTINUE:
{ {
if (continueBlock) if (continueBlock.mBlock)
{ {
UnwindDestructStack(procType, proc, block, destack, continueBlock.mStack);
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins); block->Append(jins);
block->Close(continueBlock, nullptr); block->Close(continueBlock.mBlock, nullptr);
block = new InterCodeBasicBlock(proc); block = new InterCodeBasicBlock(proc);
} }
else else
@ -3526,7 +3530,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
DestructStack* idestack = destack; DestructStack* idestack = destack;
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, eblock, lblock, inlineMapper); vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(lblock, idestack), inlineMapper);
UnwindDestructStack(procType, proc, bblock, destack, idestack); UnwindDestructStack(procType, proc, bblock, destack, idestack);
destack = idestack; destack = idestack;
@ -3616,7 +3620,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
DestructStack* idestack = destack; DestructStack* idestack = destack;
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, eblock, iblock, inlineMapper); vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(iblock, idestack), inlineMapper);
UnwindDestructStack(procType, proc, bblock, destack, idestack); UnwindDestructStack(procType, proc, bblock, destack, idestack);
destack = idestack; destack = idestack;
@ -3641,6 +3645,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_DO: case EX_DO:
{ {
DestructStack* odestack = destack;
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
@ -3650,17 +3656,27 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(jins); block->Append(jins);
block->Close(cblock, nullptr); block->Close(cblock, nullptr);
vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, eblock, cblock, inlineMapper); DestructStack* idestack = destack;
vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(cblock, idestack), inlineMapper);
UnwindDestructStack(procType, proc, cblock, destack, idestack);
destack = idestack;
TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, destack, inlineMapper); TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, destack, inlineMapper);
block = eblock; block = eblock;
UnwindDestructStack(procType, proc, block, destack, odestack);
destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
} }
case EX_SWITCH: case EX_SWITCH:
{ {
DestructStack* odestack = destack;
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
vl = Dereference(proc, exp, block, vl); vl = Dereference(proc, exp, block, vl);
vl = CoerceType(proc, exp, block, vl, TheSignedIntTypeDeclaration); vl = CoerceType(proc, exp, block, vl, TheSignedIntTypeDeclaration);
@ -3730,7 +3746,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
if (cexp->mRight) if (cexp->mRight)
TranslateExpression(procType, proc, block, cexp->mRight, destack, eblock, continueBlock, inlineMapper); TranslateExpression(procType, proc, block, cexp->mRight, destack, BranchTarget(eblock, odestack), continueBlock, inlineMapper);
sexp = sexp->mRight; sexp = sexp->mRight;
} }
@ -3739,6 +3755,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (block) if (block)
{ {
UnwindDestructStack(procType, proc, block, destack, odestack);
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins); block->Append(jins);
@ -3747,6 +3765,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block = eblock; block = eblock;
destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
} }
default: default:
@ -3917,7 +3937,7 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur
} }
default: default:
{ {
ExValue vr = TranslateExpression(procType, proc, block, exp, destack, nullptr, nullptr, inlineMapper); ExValue vr = TranslateExpression(procType, proc, block, exp, destack, BranchTarget(), BranchTarget(), inlineMapper);
vr = Dereference(proc, exp, block, vr); vr = Dereference(proc, exp, block, vr);
if (!vr.mType->IsSimpleType()) if (!vr.mType->IsSimpleType())
@ -4024,7 +4044,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
DestructStack* destack = nullptr; DestructStack* destack = nullptr;
TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, nullptr, nullptr, nullptr); TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, BranchTarget(), BranchTarget(), nullptr);
UnwindDestructStack(dec->mBase, proc, exitBlock, destack, nullptr); UnwindDestructStack(dec->mBase, proc, exitBlock, destack, nullptr);
} }

View File

@ -27,6 +27,20 @@ public:
{} {}
}; };
struct BranchTarget
{
InterCodeBasicBlock* mBlock;
DestructStack* mStack;
BranchTarget(void)
: mBlock(nullptr), mStack(nullptr)
{}
BranchTarget(InterCodeBasicBlock * block, DestructStack * stack)
: mBlock(block), mStack(stack)
{}
};
uint64 mCompilerOptions; uint64 mCompilerOptions;
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
@ -63,9 +77,9 @@ protected:
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level = 0); ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level = 0);
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type, bool checkTrunc = true); ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type, bool checkTrunc = true);
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr); ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper); void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper);
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr); ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr);
void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom); void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom);
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable); void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);