Destructor tracking of temporary variables
This commit is contained in:
parent
56740b630d
commit
6b753c1418
|
@ -1,5 +1,11 @@
|
|||
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
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -123,7 +123,7 @@ void DeclarationScope::End(const Location& loc)
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
switch (mType)
|
||||
|
@ -635,8 +777,8 @@ Expression* Expression::ConstantFold(Errors * errors)
|
|||
Declaration::Declaration(const Location& loc, DecType type)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
|
||||
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
||||
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr),
|
||||
mConstructor(nullptr), mDestructor(nullptr),
|
||||
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), mConst(nullptr),
|
||||
mConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr),
|
||||
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),
|
||||
mCompilerOptions(0), mUseCount(0)
|
||||
|
@ -653,6 +795,18 @@ int Declaration::Stride(void) const
|
|||
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* ndec = new Declaration(mLocation, mType);
|
||||
|
@ -945,6 +1099,8 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
return mIdent == dec->mIdent;
|
||||
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
||||
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)
|
||||
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
|
||||
else if (mType == DT_TYPE_FUNCTION)
|
||||
|
|
|
@ -185,7 +185,8 @@ enum ExpressionType
|
|||
EX_CONDITIONAL,
|
||||
EX_ASSUME,
|
||||
EX_BANKOF,
|
||||
EX_CONSTRUCT
|
||||
EX_CONSTRUCT,
|
||||
EX_CLEANUP,
|
||||
};
|
||||
|
||||
class Expression
|
||||
|
@ -208,6 +209,8 @@ public:
|
|||
bool HasSideEffects(void) const;
|
||||
|
||||
bool IsSame(const Expression* exp) const;
|
||||
|
||||
void Dump(int ident) const;
|
||||
};
|
||||
|
||||
class Declaration
|
||||
|
@ -219,7 +222,7 @@ public:
|
|||
Location mLocation, mEndLocation;
|
||||
DecType mType;
|
||||
Token mToken;
|
||||
Declaration* mBase, *mParams, * mNext, * mConst, * mConstructor, * mDestructor;
|
||||
Declaration* mBase, *mParams, * mNext, * mPrev, * mConst, * mConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
|
||||
Expression* mValue;
|
||||
DeclarationScope* mScope;
|
||||
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
|
||||
|
@ -249,6 +252,7 @@ public:
|
|||
Declaration* ToStriped(int stripe);
|
||||
Declaration* ToStriped(Errors* errors);
|
||||
Declaration* Clone(void);
|
||||
Declaration* Last(void);
|
||||
|
||||
int Stride(void) const;
|
||||
};
|
||||
|
|
|
@ -78,6 +78,8 @@ enum ErrorID
|
|||
ERRO_NO_MATCHING_FUNCTION_CALL,
|
||||
ERRO_AMBIGUOUS_FUNCTION_CALL,
|
||||
EERR_NO_DEFAULT_CONSTRUCTOR,
|
||||
EERR_INVALID_OPERATOR,
|
||||
EERR_MISSING_TEMP,
|
||||
|
||||
ERRR_STACK_OVERFLOW,
|
||||
ERRR_INVALID_NUMBER,
|
||||
|
|
|
@ -429,6 +429,14 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* 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_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 1
|
||||
#if 0
|
||||
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||
{
|
||||
if (!(pdec->mFlags & DTF_FPARAM_NOCONST))
|
||||
|
@ -715,7 +723,13 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
#endif
|
||||
}
|
||||
|
||||
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT)
|
||||
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 && !(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE))
|
||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||
|
||||
if (pdec)
|
||||
|
@ -734,7 +748,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
return Analyze(exp->mRight, procDec, false);
|
||||
case EX_RETURN:
|
||||
if (exp->mLeft)
|
||||
{
|
||||
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;
|
||||
case EX_SEQUENCE:
|
||||
do
|
||||
|
@ -762,6 +783,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
Analyze(exp->mLeft->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:
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
|
|
|
@ -16017,7 +16017,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mIdent->mString, "test_retparam_value");
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (stack->mDestruct)
|
||||
{
|
||||
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;
|
||||
|
@ -873,7 +873,7 @@ void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodePro
|
|||
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;
|
||||
|
||||
|
@ -1023,6 +1023,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
|
||||
Declaration* rdec = nullptr;
|
||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
||||
{
|
||||
if (lrexp)
|
||||
{
|
||||
nmapper.mResultExp = lrexp;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nindex = proc->mNumLocals++;
|
||||
nmapper.mResult = nindex;
|
||||
|
@ -1032,6 +1038,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
rdec->mBase = ftype->mBase;
|
||||
rdec->mSize = rdec->mBase->mSize;
|
||||
}
|
||||
}
|
||||
|
||||
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 = nmapper.mReturn;
|
||||
|
||||
UnwindDestructStack(ftype, proc, block, destack, nullptr, &nmapper);
|
||||
|
||||
if (rdec)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (lrexp)
|
||||
{
|
||||
return *lrexp;
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
Declaration* dec;
|
||||
|
@ -1079,6 +1292,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (!exp)
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
break;
|
||||
|
||||
case EX_CONSTRUCT:
|
||||
{
|
||||
if (exp->mLeft->mLeft)
|
||||
|
@ -1095,6 +1309,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
exp = exp->mRight;
|
||||
}
|
||||
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:
|
||||
dec = exp->mDecValue;
|
||||
switch (dec->mType)
|
||||
|
@ -2510,7 +2732,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
if (doInline)
|
||||
{
|
||||
return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr);
|
||||
return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr, lrexp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2659,6 +2881,31 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
CopyStruct(proc, exp, block, vp, vr, inlineMapper);
|
||||
#if 0
|
||||
InterInstruction* cins = new InterInstruction(texp->mLocation, IC_COPY);
|
||||
cins->mSrc[0].mType = IT_POINTER;
|
||||
cins->mSrc[0].mTemp = vr.mTemp;
|
||||
|
@ -2687,6 +2936,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
cins->mConst.mOperandSize = vp.mType->mSize;
|
||||
block->Append(cins);
|
||||
#endif
|
||||
}
|
||||
|
||||
atotal += vr.mType->mSize;
|
||||
|
@ -2931,6 +3181,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mSrc[0].mMemory = IM_INDIRECT;
|
||||
|
||||
if (inlineMapper)
|
||||
{
|
||||
if (inlineMapper->mResultExp)
|
||||
{
|
||||
ins->mSrc[1].mType = IT_POINTER;
|
||||
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ins->mCode = IC_STORE;
|
||||
ins->mSrc[1].mOperandSize = 2;
|
||||
ins->mNumOperands = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
|
@ -2948,6 +3209,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
|
||||
ins->mNumOperands = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ins->mCode = IC_RETURN_VALUE;
|
||||
|
@ -2968,6 +3230,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
|
||||
if (inlineMapper)
|
||||
{
|
||||
if (inlineMapper->mResultExp)
|
||||
{
|
||||
ains->mDst.mTemp = inlineMapper->mResultExp->mTemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
ains->mCode = IC_CONSTANT;
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
|
@ -2977,6 +3245,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ains->mConst.mVarIndex = inlineMapper->mResult;
|
||||
ains->mConst.mMemory = IM_LOCAL;
|
||||
block->Append(ains);
|
||||
}
|
||||
|
||||
ins->mCode = IC_NONE;
|
||||
}
|
||||
|
@ -3009,6 +3278,86 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mCode = IC_RETURN;
|
||||
}
|
||||
|
||||
CopyStruct(proc, exp, block, ExValue(procType->mBase, ains->mDst.mTemp), vr, inlineMapper);
|
||||
#if 0
|
||||
if (procType->mBase->mCopyConstructor)
|
||||
{
|
||||
Declaration* ccdec = procType->mBase->mCopyConstructor;
|
||||
if (ccdec->mBase->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
if (!ccdec->mLinkerObject)
|
||||
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
|
||||
|
||||
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 (procType->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
psins->mConst.mMemory = IM_FPARAM;
|
||||
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||
}
|
||||
else
|
||||
psins->mConst.mMemory = IM_PARAM;
|
||||
block->Append(psins);
|
||||
|
||||
InterInstruction* ssins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||
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;
|
||||
|
@ -3024,6 +3373,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
cins->mConst.mOperandSize = procType->mBase->mSize;
|
||||
block->Append(cins);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
vr = Dereference(proc, exp, block, vr);
|
||||
|
@ -3039,6 +3390,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mSrc[0].mTemp = vr.mTemp;
|
||||
|
||||
if (inlineMapper)
|
||||
{
|
||||
if (inlineMapper->mResultExp)
|
||||
{
|
||||
ins->mSrc[1].mType = IT_POINTER;
|
||||
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ins->mCode = IC_STORE;
|
||||
ins->mSrc[1].mOperandSize = procType->mBase->mSize;
|
||||
ins->mNumOperands = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
|
@ -3056,6 +3418,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
|
||||
ins->mNumOperands = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ins->mCode = IC_RETURN_VALUE;
|
||||
|
@ -3075,7 +3438,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mCode = IC_RETURN;
|
||||
}
|
||||
|
||||
UnwindDestructStack(procType, proc, block, destack, nullptr);
|
||||
UnwindDestructStack(procType, proc, block, destack, nullptr, inlineMapper);
|
||||
|
||||
if (ins->mCode != IC_NONE)
|
||||
block->Append(ins);
|
||||
|
@ -3097,7 +3460,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
{
|
||||
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);
|
||||
block->Append(jins);
|
||||
|
||||
|
@ -3114,7 +3477,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
{
|
||||
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);
|
||||
block->Append(jins);
|
||||
|
||||
|
@ -3508,7 +3871,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
UnwindDestructStack(procType, proc, bblock, destack, idestack);
|
||||
UnwindDestructStack(procType, proc, bblock, destack, idestack, inlineMapper);
|
||||
destack = idestack;
|
||||
|
||||
bblock->Append(jins1);
|
||||
|
@ -3544,7 +3907,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
block = eblock;
|
||||
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||
destack = odestack;
|
||||
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
|
@ -3565,7 +3928,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
DestructStack* itdestack = destack;
|
||||
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;
|
||||
|
||||
tblock->Append(jins0);
|
||||
|
@ -3575,7 +3938,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
{
|
||||
DestructStack* ifdestack = destack;
|
||||
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;
|
||||
}
|
||||
fblock->Append(jins1);
|
||||
|
@ -3583,7 +3946,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
block = eblock;
|
||||
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||
destack = odestack;
|
||||
|
||||
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);
|
||||
|
||||
UnwindDestructStack(procType, proc, bblock, destack, idestack);
|
||||
UnwindDestructStack(procType, proc, bblock, destack, idestack, inlineMapper);
|
||||
destack = idestack;
|
||||
|
||||
bblock->Append(jins2);
|
||||
|
@ -3641,7 +4004,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
block = eblock;
|
||||
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||
destack = odestack;
|
||||
|
||||
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);
|
||||
|
||||
UnwindDestructStack(procType, proc, cblock, destack, idestack);
|
||||
UnwindDestructStack(procType, proc, cblock, destack, idestack, inlineMapper);
|
||||
destack = idestack;
|
||||
|
||||
TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, destack, inlineMapper);
|
||||
|
||||
block = eblock;
|
||||
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||
destack = odestack;
|
||||
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
|
@ -3759,7 +4122,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
if (block)
|
||||
{
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
||||
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||
|
||||
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));
|
||||
|
||||
#if 0
|
||||
if (proc->mIdent && !strcmp(proc->mIdent->mString, "test_retparam_value"))
|
||||
exp->Dump(0);
|
||||
#endif
|
||||
|
||||
uint64 outerCompilerOptions = mCompilerOptions;
|
||||
mCompilerOptions = dec->mCompilerOptions;
|
||||
|
||||
|
@ -4050,7 +4418,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
|
||||
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
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);
|
||||
|
|
|
@ -59,9 +59,10 @@ protected:
|
|||
InterCodeBasicBlock * mReturn;
|
||||
int mResult, mDepth, mVarIndex;
|
||||
bool mConstExpr;
|
||||
ExValue * mResultExp;
|
||||
|
||||
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 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);
|
||||
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);
|
||||
};
|
||||
|
|
|
@ -34621,6 +34621,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
progress = true;
|
||||
}
|
||||
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_INX &&
|
||||
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;
|
||||
}
|
||||
|
||||
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 (
|
||||
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))
|
||||
|
@ -34952,7 +34986,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
if (FindPageStartAddress(i, mIns[i + 1].mAddress, addr))
|
||||
{
|
||||
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
|
||||
{
|
||||
mIns.Insert(i + 2, mIns[i + 0]);
|
||||
mIns[i + 2].mLive |= mIns[i + 1].mLive;
|
||||
}
|
||||
|
||||
int absaddr = addr + mIns[i + 0].mAddress;
|
||||
|
||||
|
@ -39997,7 +40034,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
{
|
||||
mInterProc = proc;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mapTimeTick");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "Y::Y");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
@ -41273,7 +41310,6 @@ void NativeCodeProcedure::Optimize(void)
|
|||
|
||||
} while (changed);
|
||||
|
||||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
mEntryBlock->ReduceLocalYPressure();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,6 +46,13 @@ protected:
|
|||
Expression* BuildMemberInitializer(Expression* vexp);
|
||||
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* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr);
|
||||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
||||
|
@ -65,6 +72,8 @@ protected:
|
|||
Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset);
|
||||
Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset);
|
||||
|
||||
Expression* CheckOperatorOverload(Expression* exp);
|
||||
|
||||
void AddAssemblerRegister(const Ident* ident, int value);
|
||||
|
||||
Declaration* ParseQualIdent(void);
|
||||
|
|
|
@ -1394,6 +1394,17 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_USING;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "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
|
||||
{
|
||||
mToken = TK_IDENT;
|
||||
|
|
Loading…
Reference in New Issue