Destructor tracking of temporary variables

This commit is contained in:
drmortalwombat 2023-06-25 14:25:29 +02:00
parent 56740b630d
commit 6b753c1418
14 changed files with 1898 additions and 265 deletions

View File

@ -1,5 +1,11 @@
rem @echo off rem @echo off
@call :test constructortest.cpp
@if %errorlevel% neq 0 goto :error
@call :test copyconstructor.cpp
@if %errorlevel% neq 0 goto :error
@call :test stdlibtest.c @call :test stdlibtest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error

View File

@ -0,0 +1,165 @@
#include <assert.h>
int t, n;
struct C1
{
int a;
C1(int x);
~C1(void);
};
C1::C1(int x) : a(x)
{
t += a;
n++;
}
C1::~C1(void)
{
t -= a;
}
void test_base(void)
{
n = 0;
{
C1 x(2);
C1 y(1);
}
assert(t == 0 && n == 2);
}
void test_base_loop(void)
{
n = 0;
for(int i=0; i<10; i++)
{
C1 x(2);
C1 y(1);
}
assert(t == 0 && n == 20);
}
struct C2
{
C1 c, d;
C2(void);
};
C2::C2(void)
: c(7), d(11)
{
}
void test_member(void)
{
n = 0;
{
C2 x();
C2 y();
}
assert(t == 0 && n == 4);
}
void test_member_loop(void)
{
n = 0;
for(int i=0; i<10; i++)
{
C2 x();
C2 y();
}
assert(t == 0 && n == 40);
}
struct C3
{
C2 x, y;
};
void test_default(void)
{
n = 0;
{
C3 x();
C3 y();
}
assert(t == 0 && n == 8);
}
void test_default_loop(void)
{
n = 0;
for(int i=0; i<10; i++)
{
C3 x();
C3 y();
}
assert(t == 0 && n == 80);
}
inline void test_inline_x(void)
{
C1 x(1), y(2);
}
void test_inline(void)
{
n = 0;
test_inline_x();
assert(t == 0 && n == 2);
}
inline void test_inline_xr(void)
{
C1 x(1), y(2);
{
C1 x(3);
return;
}
}
void test_inline_return(void)
{
n = 0;
test_inline_xr();
assert(t == 0 && n == 3);
}
int main(void)
{
test_base();
test_base_loop();
test_member();
test_member_loop();
test_default();
test_default_loop();
test_inline();
test_inline_return();
return 0;
}

View File

@ -0,0 +1,216 @@
#include <assert.h>
int t, n;
struct C0
{
int u;
C0(int a);
~C0(void);
};
C0::C0(int a) : u(a)
{
t += u;
n++;
}
C0::~C0(void)
{
t -= u;
}
struct C1
{
int u;
C1(int a);
~C1(void);
C1(const C1 & c);
};
C1::C1(int a) : u(a)
{
t += u;
n++;
}
C1::~C1(void)
{
t -= u;
}
C1::C1(const C1 & c) : u(c.u)
{
t += u;
n++;
}
void test_dcopy_init(void)
{
n = 0;
{
C0 x(4);
C0 y(x);
}
assert(n == 1 && t == -4);
t = 0;
}
void test_copy_init(void)
{
n = 0;
{
C1 x(4);
C1 y(x);
}
assert(n == 2 && t == 0);
}
struct C2
{
C1 a, b;
C2(void);
};
C2::C2(void) : a(1), b(3)
{}
void test_minit(void)
{
n = 0;
{
C2 x;
}
assert(n == 2 && t == 0);
}
void test_minit_copy(void)
{
n = 0;
{
C2 x;
C2 y(x);
}
assert(n == 4 && t == 0);
}
int k;
inline void test_param_fv(C2 c)
{
k += c.a.u;
}
void test_param_fr(C2 & c)
{
k += c.a.u;
}
void test_param_value(void)
{
n = 0;
{
C2 x;
test_param_fv(x);
}
assert(n == 4 && t == 0);
}
void test_param_ref(void)
{
n = 0;
{
C2 x;
test_param_fr(x);
}
assert(n == 2 && t == 0);
}
C2 test_ret_v(void)
{
C2 c;
return c;
}
C2 & test_ret_r(C2 & r)
{
return r;
}
void test_return_value(void)
{
n = 0;
{
C2 c(test_ret_v());
}
assert(n == 4 && t == 0);
}
void test_return_reference(void)
{
n = 0;
{
C2 d;
C2 c(test_ret_r(d));
}
assert(n == 2 && t == 0);
}
void test_retparam_value(void)
{
n = 0;
{
test_param_fv(test_ret_v());
}
assert(n == 4 && t == 0);
}
void test_retparam_reference(void)
{
n = 0;
{
test_param_fr(test_ret_v());
}
assert(n == 4 && t == 0);
}
int main(void)
{
#if 0
test_dcopy_init();
test_copy_init();
test_minit();
test_minit_copy();
test_param_value();
test_param_ref();
test_return_value();
#endif
test_retparam_value();
// test_retparam_reference();
return 0;
}

View File

@ -123,7 +123,7 @@ void DeclarationScope::End(const Location& loc)
} }
Expression::Expression(const Location& loc, ExpressionType type) Expression::Expression(const Location& loc, ExpressionType type)
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false) : mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr)
{ {
} }
@ -133,6 +133,148 @@ Expression::~Expression(void)
} }
void Expression::Dump(int ident) const
{
for (int i = 0; i < ident; i++)
printf("| ");
switch (mType)
{
case EX_ERROR:
printf("ERROR");
break;
case EX_VOID:
printf("VOID");
break;
case EX_CONSTANT:
printf("CONST");
break;
case EX_VARIABLE:
printf("VAR");
break;
case EX_ASSIGNMENT:
printf("ASSIGN<%s>", TokenNames[mToken]);
break;
case EX_INITIALIZATION:
printf("INIT");
break;
case EX_BINARY:
printf("BINARY<%s>", TokenNames[mToken]);
break;
case EX_RELATIONAL:
printf("RELATIONAL<%s>", TokenNames[mToken]);
break;
case EX_PREINCDEC:
printf("PREOP<%s>", TokenNames[mToken]);
break;
case EX_PREFIX:
printf("PREFIX<%s>", TokenNames[mToken]);
break;
case EX_POSTFIX:
printf("POSTFIX<%s>", TokenNames[mToken]);
break;
case EX_POSTINCDEC:
printf("POSTOP<%s>", TokenNames[mToken]);
break;
case EX_INDEX:
printf("INDEX");
break;
case EX_QUALIFY:
printf("QUALIFY");
break;
case EX_CALL:
printf("CALL");
break;
case EX_INLINE:
printf("INLINE");
break;
case EX_LIST:
printf("LIST");
break;
case EX_RETURN:
printf("RETURN");
break;
case EX_SEQUENCE:
printf("SEQUENCE");
break;
case EX_WHILE:
printf("WHILE");
break;
case EX_IF:
printf("IF");
break;
case EX_ELSE:
printf("ELSE");
break;
case EX_FOR:
printf("FOR");
break;
case EX_DO:
printf("DO");
break;
case EX_SCOPE:
printf("SCOPE");
break;
case EX_BREAK:
printf("BREAK");
break;
case EX_CONTINUE:
printf("CONTINUE");
break;
case EX_TYPE:
printf("TYPE");
break;
case EX_TYPECAST:
printf("TYPECAST");
break;
case EX_LOGICAL_AND:
printf("AND");
break;
case EX_LOGICAL_OR:
printf("OR");
break;
case EX_LOGICAL_NOT:
printf("NOT");
break;
case EX_ASSEMBLER:
printf("ASSEMBLER");
break;
case EX_UNDEFINED:
printf("UNDEFINED");
break;
case EX_SWITCH:
printf("SWITCH");
break;
case EX_CASE:
printf("CASE");
break;
case EX_DEFAULT:
printf("DEFAULT");
break;
case EX_CONDITIONAL:
printf("COND");
break;
case EX_ASSUME:
printf("ASSUME");
break;
case EX_BANKOF:
printf("BANKOF");
break;
case EX_CONSTRUCT:
printf("CONSTRUCT");
break;
case EX_CLEANUP:
printf("CLEANUP");
break;
}
printf("\n");
if (mLeft)
mLeft->Dump(ident + 1);
if (mRight)
mRight->Dump(ident + 1);
}
bool Expression::HasSideEffects(void) const bool Expression::HasSideEffects(void) const
{ {
switch (mType) switch (mType)
@ -635,8 +777,8 @@ Expression* Expression::ConstantFold(Errors * errors)
Declaration::Declaration(const Location& loc, DecType type) Declaration::Declaration(const Location& loc, DecType type)
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr), : mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), mConst(nullptr),
mConstructor(nullptr), mDestructor(nullptr), mConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1), mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
mCompilerOptions(0), mUseCount(0) mCompilerOptions(0), mUseCount(0)
@ -653,6 +795,18 @@ int Declaration::Stride(void) const
return mStride > 0 ? mStride : mBase->mSize; return mStride > 0 ? mStride : mBase->mSize;
} }
Declaration* Declaration::Last(void)
{
mPrev = nullptr;
Declaration* p = this;
while (p->mNext)
{
p->mNext->mPrev = p;
p = p->mNext;
}
return p;
}
Declaration* Declaration::Clone(void) Declaration* Declaration::Clone(void)
{ {
Declaration* ndec = new Declaration(mLocation, mType); Declaration* ndec = new Declaration(mLocation, mType);
@ -945,6 +1099,8 @@ bool Declaration::IsSame(const Declaration* dec) const
return mIdent == dec->mIdent; return mIdent == dec->mIdent;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase); return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_REFERENCE)
return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT) else if (mType == DT_TYPE_STRUCT)
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize); return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
else if (mType == DT_TYPE_FUNCTION) else if (mType == DT_TYPE_FUNCTION)

View File

@ -185,7 +185,8 @@ enum ExpressionType
EX_CONDITIONAL, EX_CONDITIONAL,
EX_ASSUME, EX_ASSUME,
EX_BANKOF, EX_BANKOF,
EX_CONSTRUCT EX_CONSTRUCT,
EX_CLEANUP,
}; };
class Expression class Expression
@ -208,6 +209,8 @@ public:
bool HasSideEffects(void) const; bool HasSideEffects(void) const;
bool IsSame(const Expression* exp) const; bool IsSame(const Expression* exp) const;
void Dump(int ident) const;
}; };
class Declaration class Declaration
@ -219,7 +222,7 @@ public:
Location mLocation, mEndLocation; Location mLocation, mEndLocation;
DecType mType; DecType mType;
Token mToken; Token mToken;
Declaration* mBase, *mParams, * mNext, * mConst, * mConstructor, * mDestructor; Declaration* mBase, *mParams, * mNext, * mPrev, * mConst, * mConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
Expression* mValue; Expression* mValue;
DeclarationScope* mScope; DeclarationScope* mScope;
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe; int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
@ -249,6 +252,7 @@ public:
Declaration* ToStriped(int stripe); Declaration* ToStriped(int stripe);
Declaration* ToStriped(Errors* errors); Declaration* ToStriped(Errors* errors);
Declaration* Clone(void); Declaration* Clone(void);
Declaration* Last(void);
int Stride(void) const; int Stride(void) const;
}; };

View File

@ -14,7 +14,7 @@ class Ident;
enum ErrorID enum ErrorID
{ {
EINFO_GENERIC = 1000, EINFO_GENERIC = 1000,
EWARN_GENERIC = 2000, EWARN_GENERIC = 2000,
EWARN_CONSTANT_TRUNCATED, EWARN_CONSTANT_TRUNCATED,
EWARN_UNKNOWN_PRAGMA, EWARN_UNKNOWN_PRAGMA,
@ -78,6 +78,8 @@ enum ErrorID
ERRO_NO_MATCHING_FUNCTION_CALL, ERRO_NO_MATCHING_FUNCTION_CALL,
ERRO_AMBIGUOUS_FUNCTION_CALL, ERRO_AMBIGUOUS_FUNCTION_CALL,
EERR_NO_DEFAULT_CONSTRUCTOR, EERR_NO_DEFAULT_CONSTRUCTOR,
EERR_INVALID_OPERATOR,
EERR_MISSING_TEMP,
ERRR_STACK_OVERFLOW, ERRR_STACK_OVERFLOW,
ERRR_INVALID_NUMBER, ERRR_INVALID_NUMBER,

View File

@ -429,6 +429,14 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
mFunctions.Push(dec); mFunctions.Push(dec);
Declaration* pdec = dec->mBase->mParams;
while (pdec)
{
if (pdec->mBase->mType == DT_TYPE_STRUCT && (pdec->mBase->mCopyConstructor || pdec->mBase->mDestructor))
dec->mBase->mFlags |= DTF_STACKCALL;
pdec = pdec->mNext;
}
dec->mFlags |= DTF_ANALYZED; dec->mFlags |= DTF_ANALYZED;
dec->mFlags |= DTF_FUNC_INTRSAVE; dec->mFlags |= DTF_FUNC_INTRSAVE;
@ -679,7 +687,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER))) if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER)))
{ {
#if 1 #if 0
if (mCompilerOptions & COPT_OPTIMIZE_BASIC) if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
{ {
if (!(pdec->mFlags & DTF_FPARAM_NOCONST)) if (!(pdec->mFlags & DTF_FPARAM_NOCONST))
@ -714,8 +722,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
} }
#endif #endif
} }
if (pdec && pdec->mBase->mType == DT_TYPE_STRUCT && pdec->mBase->mCopyConstructor)
{
AnalyzeProcedure(pdec->mBase->mCopyConstructor->mValue, pdec->mBase->mCopyConstructor);
RegisterCall(procDec, pdec->mBase->mCopyConstructor);
}
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT) if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT && !(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE))
ldec->mBase->mFlags |= DTF_STACKCALL; ldec->mBase->mFlags |= DTF_STACKCALL;
if (pdec) if (pdec)
@ -734,7 +748,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
return Analyze(exp->mRight, procDec, false); return Analyze(exp->mRight, procDec, false);
case EX_RETURN: case EX_RETURN:
if (exp->mLeft) if (exp->mLeft)
{
RegisterProc(Analyze(exp->mLeft, procDec, false)); RegisterProc(Analyze(exp->mLeft, procDec, false));
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
{
AnalyzeProcedure(procDec->mBase->mBase->mCopyConstructor->mValue, procDec->mBase->mBase->mCopyConstructor);
RegisterCall(procDec, procDec->mBase->mBase->mCopyConstructor);
}
}
break; break;
case EX_SEQUENCE: case EX_SEQUENCE:
do do
@ -761,6 +782,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
if (exp->mLeft->mRight) if (exp->mLeft->mRight)
Analyze(exp->mLeft->mRight, procDec, false); Analyze(exp->mLeft->mRight, procDec, false);
return Analyze(exp->mRight, procDec, false); return Analyze(exp->mRight, procDec, false);
case EX_CLEANUP:
Analyze(exp->mRight, procDec, false);
return Analyze(exp->mLeft, procDec, lhs);
case EX_WHILE: case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;

View File

@ -16017,7 +16017,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main"); CheckFunc = !strcmp(mIdent->mString, "test_retparam_value");
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];

View File

@ -856,14 +856,14 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
} }
} }
void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack* bottom) void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack* bottom, InlineMapper* inlineMapper)
{ {
while (stack && stack != bottom) while (stack && stack != bottom)
{ {
if (stack->mDestruct) if (stack->mDestruct)
{ {
DestructStack* destack = nullptr; DestructStack* destack = nullptr;
TranslateExpression(procType, proc, block, stack->mDestruct, destack, BranchTarget(), BranchTarget(), nullptr); TranslateExpression(procType, proc, block, stack->mDestruct, destack, BranchTarget(), BranchTarget(), inlineMapper);
} }
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, const BranchTarget& breakBlock, const BranchTarget& 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, ExValue* lrexp)
{ {
DestructStack* destack = nullptr; DestructStack* destack = nullptr;
@ -1024,13 +1024,20 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
Declaration* rdec = nullptr; Declaration* rdec = nullptr;
if (ftype->mBase->mType != DT_TYPE_VOID) if (ftype->mBase->mType != DT_TYPE_VOID)
{ {
int nindex = proc->mNumLocals++; if (lrexp)
nmapper.mResult = nindex; {
nmapper.mResultExp = lrexp;
}
else
{
int nindex = proc->mNumLocals++;
nmapper.mResult = nindex;
rdec = new Declaration(ftype->mLocation, DT_VARIABLE); rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
rdec->mVarIndex = nindex; rdec->mVarIndex = nindex;
rdec->mBase = ftype->mBase; rdec->mBase = ftype->mBase;
rdec->mSize = rdec->mBase->mSize; rdec->mSize = rdec->mBase->mSize;
}
} }
vl = TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper); vl = TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
@ -1041,6 +1048,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
block->Close(nmapper.mReturn, nullptr); block->Close(nmapper.mReturn, nullptr);
block = nmapper.mReturn; block = nmapper.mReturn;
UnwindDestructStack(ftype, proc, block, destack, nullptr, &nmapper);
if (rdec) if (rdec)
{ {
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_CONSTANT); InterInstruction* ins = new InterInstruction(exp->mLocation, IC_CONSTANT);
@ -1055,10 +1064,214 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
return ExValue(rdec->mBase, ins->mDst.mTemp, 1); return ExValue(rdec->mBase, ins->mDst.mTemp, 1);
} }
else if (lrexp)
{
return *lrexp;
}
else else
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
} }
void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper)
{
if (vl.mType->mCopyConstructor)
{
Declaration* ccdec = vl.mType->mCopyConstructor;
if (!ccdec->mLinkerObject)
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
bool canInline = (mCompilerOptions & COPT_OPTIMIZE_INLINE) && !(inlineMapper && inlineMapper->mDepth > 10);
bool doInline = false;
if (canInline)
{
if (ccdec->mFlags & DTF_INLINE)
{
if ((ccdec->mFlags & DTF_REQUEST_INLINE) || (mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE))
{
if (proc->mNativeProcedure || !(ccdec->mFlags & DTF_NATIVE))
doInline = true;
}
}
}
if (doInline)
{
DestructStack* destack = nullptr;
Expression* fexp = ccdec->mValue;
Declaration* ftype = ccdec->mBase;
InlineMapper nmapper;
nmapper.mReturn = new InterCodeBasicBlock(proc);
nmapper.mVarIndex = proc->mNumLocals;
nmapper.mConstExpr = false;
proc->mNumLocals += ccdec->mNumVars;
if (inlineMapper)
nmapper.mDepth = inlineMapper->mDepth + 1;
Declaration* pdec = ftype->mParams;
int nindex = proc->mNumLocals++;
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
ains->mConst.mMemory = IM_LOCAL;
ains->mConst.mVarIndex = nindex;
if (!(pdec->mFlags & DTF_FPARAM_CONST))
nmapper.mParams[pdec->mVarIndex] = nindex;
vdec->mVarIndex = nindex;
vdec->mBase = pdec->mBase;
ains->mConst.mOperandSize = 2;
vdec->mSize = ains->mConst.mOperandSize;
vdec->mIdent = pdec->mIdent;
vdec->mQualIdent = pdec->mQualIdent;
block->Append(ains);
InterInstruction* wins = new InterInstruction(exp->mLocation, IC_STORE);
wins->mSrc[1].mMemory = IM_INDIRECT;
wins->mSrc[0].mType = InterTypeOf(vl.mType);;
wins->mSrc[0].mTemp = vl.mTemp;
wins->mSrc[1].mType = IT_POINTER;
wins->mSrc[1].mTemp = ains->mDst.mTemp;
wins->mSrc[1].mOperandSize = 2;
if (!(pdec->mFlags & DTF_FPARAM_CONST))
block->Append(wins);
pdec = pdec->mNext;
nindex = proc->mNumLocals++;
vdec = new Declaration(exp->mLocation, DT_VARIABLE);
ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
ains->mConst.mMemory = IM_LOCAL;
ains->mConst.mVarIndex = nindex;
if (!(pdec->mFlags & DTF_FPARAM_CONST))
nmapper.mParams[pdec->mVarIndex] = nindex;
vdec->mVarIndex = nindex;
vdec->mBase = pdec->mBase;
ains->mConst.mOperandSize = 2;
vdec->mSize = ains->mConst.mOperandSize;
vdec->mIdent = pdec->mIdent;
vdec->mQualIdent = pdec->mQualIdent;
block->Append(ains);
wins = new InterInstruction(exp->mLocation, IC_STORE);
wins->mSrc[1].mMemory = IM_INDIRECT;
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
wins->mSrc[0].mTemp = vr.mTemp;
wins->mSrc[1].mType = IT_POINTER;
wins->mSrc[1].mTemp = ains->mDst.mTemp;
wins->mSrc[1].mOperandSize = 2;
if (!(pdec->mFlags & DTF_FPARAM_CONST))
block->Append(wins);
TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins);
block->Close(nmapper.mReturn, nullptr);
block = nmapper.mReturn;
}
else if (ccdec->mBase->mFlags & DTF_FASTCALL)
{
InterInstruction* psins = new InterInstruction(exp->mLocation, IC_CONSTANT);
psins->mDst.mType = IT_POINTER;
psins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
psins->mConst.mVarIndex = 0;
psins->mConst.mIntConst = 0;
psins->mConst.mOperandSize = 2;
if (ccdec->mBase->mFlags & DTF_FASTCALL)
{
psins->mConst.mMemory = IM_FFRAME;
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
}
else
psins->mConst.mMemory = IM_FRAME;
block->Append(psins);
InterInstruction* ssins = new InterInstruction(exp->mLocation, IC_STORE);
ssins->mSrc[0].mType = IT_POINTER;
ssins->mSrc[0].mTemp = vl.mTemp;
ssins->mSrc[0].mMemory = IM_INDIRECT;
ssins->mSrc[0].mOperandSize = 2;
ssins->mSrc[1] = psins->mDst;
block->Append(ssins);
InterInstruction* plins = new InterInstruction(exp->mLocation, IC_CONSTANT);
plins->mDst.mType = IT_POINTER;
plins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
plins->mConst.mVarIndex = 2;
plins->mConst.mIntConst = 0;
plins->mConst.mOperandSize = 2;
if (ccdec->mBase->mFlags & DTF_FASTCALL)
{
plins->mConst.mMemory = IM_FFRAME;
plins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
}
else
plins->mConst.mMemory = IM_FRAME;
block->Append(plins);
InterInstruction* slins = new InterInstruction(exp->mLocation, IC_STORE);
slins->mSrc[0].mType = IT_POINTER;
slins->mSrc[0].mTemp = vr.mTemp;
slins->mSrc[0].mMemory = IM_INDIRECT;
slins->mSrc[0].mOperandSize = 2;
slins->mSrc[1] = plins->mDst;
block->Append(slins);
proc->AddCalledFunction(proc->mModule->mProcedures[ccdec->mVarIndex]);
InterInstruction* pcins = new InterInstruction(exp->mLocation, IC_CONSTANT);
pcins->mDst.mType = IT_POINTER;
pcins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
pcins->mConst.mType = IT_POINTER;
pcins->mConst.mVarIndex = ccdec->mVarIndex;
pcins->mConst.mIntConst = 0;
pcins->mConst.mOperandSize = 2;
pcins->mConst.mMemory = IM_GLOBAL;
pcins->mConst.mLinkerObject = ccdec->mLinkerObject;
block->Append(pcins);
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CALL);
if (ccdec->mFlags & DTF_NATIVE)
cins->mCode = IC_CALL_NATIVE;
else
cins->mCode = IC_CALL;
cins->mSrc[0] = pcins->mDst;
cins->mNumOperands = 1;
block->Append(cins);
}
}
else
{
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vr.mTemp;
cins->mSrc[0].mMemory = IM_INDIRECT;
cins->mSrc[0].mOperandSize = vr.mType->mSize;
cins->mSrc[0].mStride = vr.mType->mStripe;
cins->mSrc[1].mOperandSize = vl.mType->mSize;
cins->mSrc[1].mType = IT_POINTER;
cins->mSrc[1].mTemp = vl.mTemp;
cins->mSrc[1].mMemory = IM_INDIRECT;
cins->mConst.mOperandSize = vl.mType->mSize;
block->Append(cins);
}
}
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget& breakBlock, const BranchTarget& 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;
@ -1079,6 +1292,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (!exp) if (!exp)
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
break; break;
case EX_CONSTRUCT: case EX_CONSTRUCT:
{ {
if (exp->mLeft->mLeft) if (exp->mLeft->mLeft)
@ -1095,6 +1309,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
exp = exp->mRight; exp = exp->mRight;
} }
break; break;
case EX_CLEANUP:
{
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper);
return vl;
}
case EX_CONSTANT: case EX_CONSTANT:
dec = exp->mDecValue; dec = exp->mDecValue;
switch (dec->mType) switch (dec->mType)
@ -2510,7 +2732,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (doInline) if (doInline)
{ {
return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr); return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr, lrexp);
} }
else else
{ {
@ -2659,6 +2881,31 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1); ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE && texp->mType == EX_CALL)
{
mErrors->Error(texp->mLocation, EERR_MISSING_TEMP, "Missing temporary variable");
#if 0
int nindex = proc->mNumLocals++;
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
vdec->mVarIndex = nindex;
vdec->mBase = pdec->mBase->mBase;
vdec->mSize = pdec->mBase->mBase->mSize;
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
vins->mDst.mType = IT_POINTER;
vins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
vins->mConst.mMemory = IM_LOCAL;
vins->mConst.mVarIndex = nindex;
vins->mConst.mOperandSize = vdec->mSize;
block->Append(vins);
vp.mType = pdec->mBase->mBase;
vp.mTemp = vins->mDst.mTemp;
#endif
}
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp);
if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION))
@ -2673,6 +2920,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (vp.mTemp != vr.mTemp) if (vp.mTemp != vr.mTemp)
{ {
CopyStruct(proc, exp, block, vp, vr, inlineMapper);
#if 0
InterInstruction* cins = new InterInstruction(texp->mLocation, IC_COPY); InterInstruction* cins = new InterInstruction(texp->mLocation, IC_COPY);
cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vr.mTemp; cins->mSrc[0].mTemp = vr.mTemp;
@ -2687,6 +2936,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mConst.mOperandSize = vp.mType->mSize; cins->mConst.mOperandSize = vp.mType->mSize;
block->Append(cins); block->Append(cins);
#endif
} }
atotal += vr.mType->mSize; atotal += vr.mType->mSize;
@ -2932,21 +3182,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (inlineMapper) if (inlineMapper)
{ {
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT); if (inlineMapper->mResultExp)
ains->mDst.mType = IT_POINTER; {
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); ins->mSrc[1].mType = IT_POINTER;
ains->mConst.mOperandSize = procType->mBase->mSize; ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
ains->mConst.mIntConst = 0; ins->mSrc[1].mMemory = IM_INDIRECT;
ains->mConst.mVarIndex = inlineMapper->mResult;; ins->mCode = IC_STORE;
ains->mConst.mMemory = IM_LOCAL; ins->mSrc[1].mOperandSize = 2;
block->Append(ains); ins->mNumOperands = 2;
}
else
{
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ains->mConst.mOperandSize = procType->mBase->mSize;
ains->mConst.mIntConst = 0;
ains->mConst.mVarIndex = inlineMapper->mResult;;
ains->mConst.mMemory = IM_LOCAL;
block->Append(ains);
ins->mSrc[1].mType = ains->mDst.mType; ins->mSrc[1].mType = ains->mDst.mType;
ins->mSrc[1].mTemp = ains->mDst.mTemp; ins->mSrc[1].mTemp = ains->mDst.mTemp;
ins->mSrc[1].mMemory = IM_INDIRECT; ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mCode = IC_STORE; ins->mCode = IC_STORE;
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize; ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
ins->mNumOperands = 2; ins->mNumOperands = 2;
}
} }
else else
{ {
@ -2969,14 +3231,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (inlineMapper) if (inlineMapper)
{ {
ains->mCode = IC_CONSTANT; if (inlineMapper->mResultExp)
ains->mDst.mType = IT_POINTER; {
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER); ains->mDst.mTemp = inlineMapper->mResultExp->mTemp;
ains->mConst.mOperandSize = procType->mBase->mSize; }
ains->mConst.mIntConst = 0; else
ains->mConst.mVarIndex = inlineMapper->mResult; {
ains->mConst.mMemory = IM_LOCAL; ains->mCode = IC_CONSTANT;
block->Append(ains); ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
ains->mConst.mOperandSize = procType->mBase->mSize;
ains->mConst.mIntConst = 0;
ains->mConst.mVarIndex = inlineMapper->mResult;
ains->mConst.mMemory = IM_LOCAL;
block->Append(ains);
}
ins->mCode = IC_NONE; ins->mCode = IC_NONE;
} }
@ -3009,20 +3278,102 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mCode = IC_RETURN; ins->mCode = IC_RETURN;
} }
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY); CopyStruct(proc, exp, block, ExValue(procType->mBase, ains->mDst.mTemp), vr, inlineMapper);
cins->mSrc[0].mType = IT_POINTER; #if 0
cins->mSrc[0].mTemp = vr.mTemp; if (procType->mBase->mCopyConstructor)
cins->mSrc[0].mMemory = IM_INDIRECT; {
cins->mSrc[0].mOperandSize = procType->mBase->mSize; Declaration* ccdec = procType->mBase->mCopyConstructor;
cins->mSrc[0].mStride = vr.mType->mStripe; if (ccdec->mBase->mFlags & DTF_FASTCALL)
{
if (!ccdec->mLinkerObject)
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
cins->mSrc[1].mOperandSize = procType->mBase->mSize; InterInstruction* psins = new InterInstruction(exp->mLocation, IC_CONSTANT);
cins->mSrc[1].mType = IT_POINTER; psins->mDst.mType = IT_POINTER;
cins->mSrc[1].mTemp = ains->mDst.mTemp; psins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
cins->mSrc[1].mMemory = IM_INDIRECT; psins->mConst.mVarIndex = 0;
psins->mConst.mIntConst = 0;
psins->mConst.mOperandSize = 2;
if (procType->mFlags & DTF_FASTCALL)
{
psins->mConst.mMemory = IM_FPARAM;
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
}
else
psins->mConst.mMemory = IM_PARAM;
block->Append(psins);
cins->mConst.mOperandSize = procType->mBase->mSize; InterInstruction* ssins = new InterInstruction(exp->mLocation, IC_STORE);
block->Append(cins); ssins->mSrc[0] = ains->mDst;
ssins->mSrc[1] = psins->mDst;
block->Append(ssins);
InterInstruction* plins = new InterInstruction(exp->mLocation, IC_CONSTANT);
plins->mDst.mType = IT_POINTER;
plins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
plins->mConst.mVarIndex = 2;
plins->mConst.mIntConst = 0;
plins->mConst.mOperandSize = 2;
if (procType->mFlags & DTF_FASTCALL)
{
plins->mConst.mMemory = IM_FPARAM;
plins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
}
else
plins->mConst.mMemory = IM_PARAM;
block->Append(plins);
InterInstruction* slins = new InterInstruction(exp->mLocation, IC_STORE);
slins->mSrc[0].mType = IT_POINTER;
slins->mSrc[0].mTemp = vr.mTemp;
slins->mSrc[0].mMemory = IM_INDIRECT;
slins->mSrc[0].mOperandSize = procType->mBase->mSize;
slins->mSrc[0].mStride = vr.mType->mStripe;
slins->mSrc[1] = plins->mDst;
block->Append(slins);
proc->AddCalledFunction(proc->mModule->mProcedures[ccdec->mVarIndex]);
InterInstruction* pcins = new InterInstruction(exp->mLocation, IC_CONSTANT);
pcins->mDst.mType = IT_POINTER;
pcins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
pcins->mConst.mType = IT_POINTER;
pcins->mConst.mVarIndex = ccdec->mVarIndex;
pcins->mConst.mIntConst = 0;
pcins->mConst.mOperandSize = 2;
pcins->mConst.mMemory = IM_GLOBAL;
pcins->mConst.mLinkerObject = ccdec->mLinkerObject;
block->Append(pcins);
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CALL);
if (ccdec->mFlags & DTF_NATIVE)
cins->mCode = IC_CALL_NATIVE;
else
cins->mCode = IC_CALL;
cins->mSrc[0] = pcins->mDst;
cins->mNumOperands = 1;
block->Append(cins);
}
}
else
{
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vr.mTemp;
cins->mSrc[0].mMemory = IM_INDIRECT;
cins->mSrc[0].mOperandSize = procType->mBase->mSize;
cins->mSrc[0].mStride = vr.mType->mStripe;
cins->mSrc[1].mOperandSize = procType->mBase->mSize;
cins->mSrc[1].mType = IT_POINTER;
cins->mSrc[1].mTemp = ains->mDst.mTemp;
cins->mSrc[1].mMemory = IM_INDIRECT;
cins->mConst.mOperandSize = procType->mBase->mSize;
block->Append(cins);
}
#endif
} }
else else
{ {
@ -3040,21 +3391,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (inlineMapper) if (inlineMapper)
{ {
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT); if (inlineMapper->mResultExp)
ains->mDst.mType = IT_POINTER; {
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); ins->mSrc[1].mType = IT_POINTER;
ains->mConst.mOperandSize = procType->mBase->mSize; ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
ains->mConst.mIntConst = 0; ins->mSrc[1].mMemory = IM_INDIRECT;
ains->mConst.mVarIndex = inlineMapper->mResult;; ins->mCode = IC_STORE;
ains->mConst.mMemory = IM_LOCAL; ins->mSrc[1].mOperandSize = procType->mBase->mSize;
block->Append(ains); ins->mNumOperands = 2;
}
else
{
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ains->mConst.mOperandSize = procType->mBase->mSize;
ains->mConst.mIntConst = 0;
ains->mConst.mVarIndex = inlineMapper->mResult;;
ains->mConst.mMemory = IM_LOCAL;
block->Append(ains);
ins->mSrc[1].mType = ains->mDst.mType; ins->mSrc[1].mType = ains->mDst.mType;
ins->mSrc[1].mTemp = ains->mDst.mTemp; ins->mSrc[1].mTemp = ains->mDst.mTemp;
ins->mSrc[1].mMemory = IM_INDIRECT; ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mCode = IC_STORE; ins->mCode = IC_STORE;
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize; ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
ins->mNumOperands = 2; ins->mNumOperands = 2;
}
} }
else else
{ {
@ -3075,7 +3438,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mCode = IC_RETURN; ins->mCode = IC_RETURN;
} }
UnwindDestructStack(procType, proc, block, destack, nullptr); UnwindDestructStack(procType, proc, block, destack, nullptr, inlineMapper);
if (ins->mCode != IC_NONE) if (ins->mCode != IC_NONE)
block->Append(ins); block->Append(ins);
@ -3097,7 +3460,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{ {
if (breakBlock.mBlock) if (breakBlock.mBlock)
{ {
UnwindDestructStack(procType, proc, block, destack, breakBlock.mStack); UnwindDestructStack(procType, proc, block, destack, breakBlock.mStack, inlineMapper);
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins); block->Append(jins);
@ -3114,7 +3477,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{ {
if (continueBlock.mBlock) if (continueBlock.mBlock)
{ {
UnwindDestructStack(procType, proc, block, destack, continueBlock.mStack); UnwindDestructStack(procType, proc, block, destack, continueBlock.mStack, inlineMapper);
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
block->Append(jins); block->Append(jins);
@ -3508,7 +3871,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
UnwindDestructStack(procType, proc, block, destack, odestack); UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
destack = odestack; destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
@ -3536,7 +3899,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(lblock, idestack), 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, inlineMapper);
destack = idestack; destack = idestack;
bblock->Append(jins1); bblock->Append(jins1);
@ -3544,7 +3907,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block = eblock; block = eblock;
UnwindDestructStack(procType, proc, block, destack, odestack); UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
destack = odestack; destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
@ -3565,7 +3928,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
DestructStack* itdestack = destack; DestructStack* itdestack = destack;
vr = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper);
UnwindDestructStack(procType, proc, tblock, destack, itdestack); UnwindDestructStack(procType, proc, tblock, destack, itdestack, inlineMapper);
destack = itdestack; destack = itdestack;
tblock->Append(jins0); tblock->Append(jins0);
@ -3575,7 +3938,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{ {
DestructStack* ifdestack = destack; DestructStack* ifdestack = destack;
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper);
UnwindDestructStack(procType, proc, fblock, destack, ifdestack); UnwindDestructStack(procType, proc, fblock, destack, ifdestack, inlineMapper);
destack = ifdestack; destack = ifdestack;
} }
fblock->Append(jins1); fblock->Append(jins1);
@ -3583,7 +3946,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block = eblock; block = eblock;
UnwindDestructStack(procType, proc, block, destack, odestack); UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
destack = odestack; destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
@ -3626,7 +3989,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(iblock, idestack), 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, inlineMapper);
destack = idestack; destack = idestack;
bblock->Append(jins2); bblock->Append(jins2);
@ -3641,7 +4004,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block = eblock; block = eblock;
UnwindDestructStack(procType, proc, block, destack, odestack); UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
destack = odestack; destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
@ -3664,14 +4027,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(cblock, idestack), inlineMapper); vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(cblock, idestack), inlineMapper);
UnwindDestructStack(procType, proc, cblock, destack, idestack); UnwindDestructStack(procType, proc, cblock, destack, idestack, inlineMapper);
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); UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
destack = odestack; destack = odestack;
return ExValue(TheVoidTypeDeclaration); return ExValue(TheVoidTypeDeclaration);
@ -3759,7 +4122,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (block) if (block)
{ {
UnwindDestructStack(procType, proc, block, destack, odestack); UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
@ -3962,6 +4325,11 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
{ {
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE)); InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE));
#if 0
if (proc->mIdent && !strcmp(proc->mIdent->mString, "test_retparam_value"))
exp->Dump(0);
#endif
uint64 outerCompilerOptions = mCompilerOptions; uint64 outerCompilerOptions = mCompilerOptions;
mCompilerOptions = dec->mCompilerOptions; mCompilerOptions = dec->mCompilerOptions;
@ -4050,7 +4418,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, BranchTarget(), BranchTarget(), 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, nullptr);
} }
else else
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString); mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);

View File

@ -59,9 +59,10 @@ protected:
InterCodeBasicBlock * mReturn; InterCodeBasicBlock * mReturn;
int mResult, mDepth, mVarIndex; int mResult, mDepth, mVarIndex;
bool mConstExpr; bool mConstExpr;
ExValue * mResultExp;
InlineMapper(void) InlineMapper(void)
: mParams(-1), mResult(-1), mDepth(0) : mParams(-1), mResult(-1), mDepth(0), mResultExp(nullptr)
{} {}
}; };
@ -79,8 +80,9 @@ protected:
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, const BranchTarget & breakBlock, const BranchTarget& 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, const BranchTarget& breakBlock, const BranchTarget& 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, ExValue* lrexp);
void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper);
void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom); void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom, InlineMapper* inlineMapper);
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable); void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
}; };

View File

@ -34621,6 +34621,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if ( else if (
mIns[i + 0].mType == ASMIT_INX && mIns[i + 0].mType == ASMIT_INX &&
mIns[i + 1].mType == ASMIT_DEX && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z)) mIns[i + 1].mType == ASMIT_DEX && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
@ -34654,6 +34655,39 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_DEX)
{
mIns[i + 0].mAddress = (mIns[i + 0].mAddress - 1) & 255;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_INX)
{
mIns[i + 0].mAddress = (mIns[i + 0].mAddress + 1) & 255;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_DEY)
{
mIns[i + 0].mAddress = (mIns[i + 0].mAddress - 1) & 255;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_INY)
{
mIns[i + 0].mAddress = (mIns[i + 0].mAddress + 1) & 255;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X) && mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X) &&
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A)) mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
@ -34952,7 +34986,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (FindPageStartAddress(i, mIns[i + 1].mAddress, addr)) if (FindPageStartAddress(i, mIns[i + 1].mAddress, addr))
{ {
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
{
mIns.Insert(i + 2, mIns[i + 0]); mIns.Insert(i + 2, mIns[i + 0]);
mIns[i + 2].mLive |= mIns[i + 1].mLive;
}
int absaddr = addr + mIns[i + 0].mAddress; int absaddr = addr + mIns[i + 0].mAddress;
@ -39997,7 +40034,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mapTimeTick"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "Y::Y");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -41273,7 +41310,6 @@ void NativeCodeProcedure::Optimize(void)
} while (changed); } while (changed);
#if 1 #if 1
ResetVisited(); ResetVisited();
mEntryBlock->ReduceLocalYPressure(); mEntryBlock->ReduceLocalYPressure();

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,13 @@ protected:
Expression* BuildMemberInitializer(Expression* vexp); Expression* BuildMemberInitializer(Expression* vexp);
void PrependMemberConstructor(Declaration* pthis, Declaration* cfunc); void PrependMemberConstructor(Declaration* pthis, Declaration* cfunc);
void AddDefaultConstructors(Declaration* pthis);
void ParseVariableInit(Declaration* ndec);
Expression * AddFunctionCallRefReturned(Expression * exp);
Expression* CleanupExpression(Expression* exp);
Declaration* ParseBaseTypeDeclaration(uint64 flags); Declaration* ParseBaseTypeDeclaration(uint64 flags);
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr); Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr);
Declaration* ParseStructDeclaration(uint64 flags, DecType dt); Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
@ -65,6 +72,8 @@ protected:
Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset); Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset);
Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset); Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset);
Expression* CheckOperatorOverload(Expression* exp);
void AddAssemblerRegister(const Ident* ident, int value); void AddAssemblerRegister(const Ident* ident, int value);
Declaration* ParseQualIdent(void); Declaration* ParseQualIdent(void);

View File

@ -1394,6 +1394,17 @@ void Scanner::NextRawToken(void)
mToken = TK_USING; mToken = TK_USING;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this"))
mToken = TK_THIS; mToken = TK_THIS;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
{
NextRawToken();
if (mToken == TK_ASSIGN)
{
mToken = TK_IDENT;
mTokenIdent = Ident::Unique("operator=");
}
else
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
}
else else
{ {
mToken = TK_IDENT; mToken = TK_IDENT;