Fix stacked fastcall invokation

This commit is contained in:
drmortalwombat 2021-12-09 12:11:36 +01:00
parent 1ac0c2f46a
commit cf9f38d4dc
3 changed files with 40 additions and 1 deletions

View File

@ -15,6 +15,9 @@ if %errorlevel% neq 0 goto :error
call :test recursiontest.c call :test recursiontest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
call :test fastcalltest.c
if %errorlevel% neq 0 goto :error
call :test strcmptest.c call :test strcmptest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error

28
autotest/fastcalltest.c Normal file
View File

@ -0,0 +1,28 @@
#include <assert.h>
#include <stdio.h>
int p1(int a, int b)
{
return a + b;
}
int p2(int a, int b)
{
return a * b;
}
int c1(int x)
{
return x;
}
int c2(int x)
{
return c1(x);
}
int main(void)
{
return p1(5, p2(c2(2), c2(4))) - 13;
}

View File

@ -2161,6 +2161,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else else
proc->CallsFunctionPointer(); proc->CallsFunctionPointer();
GrowingArray<InterInstruction*> defins(nullptr);
Declaration* pdec = ftype->mParams; Declaration* pdec = ftype->mParams;
Expression* pex = exp->mRight; Expression* pex = exp->mRight;
while (pex) while (pex)
@ -2280,6 +2282,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else else
wins->mSrc[1].mOperandSize = 2; wins->mSrc[1].mOperandSize = 2;
if (ftype->mFlags & DTF_FASTCALL)
defins.Push(wins);
else
block->Append(wins); block->Append(wins);
atotal += wins->mSrc[1].mOperandSize; atotal += wins->mSrc[1].mOperandSize;
@ -2292,6 +2297,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (pdec) if (pdec)
mErrors->Error(exp->mLocation, EERR_WRONG_PARAMETER, "Not enough arguments for function call"); mErrors->Error(exp->mLocation, EERR_WRONG_PARAMETER, "Not enough arguments for function call");
for (int i = 0; i < defins.Size(); i++)
block->Append(defins[i]);
InterInstruction * cins = new InterInstruction(); InterInstruction * cins = new InterInstruction();
if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE) if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
cins->mCode = IC_CALL_NATIVE; cins->mCode = IC_CALL_NATIVE;