1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Fixed delegates with lowered return types

This commit is contained in:
Brian Fiete 2021-07-12 07:55:36 -07:00
parent 5f2d01ac72
commit 401ab0c98e
4 changed files with 40 additions and 12 deletions

View file

@ -1135,7 +1135,7 @@ void BfModule::SetupIRBuilder(bool dbgVerifyCodeGen)
{ {
// We almost always want this to be 'false' unless we need need to be able to inspect the generated LLVM // We almost always want this to be 'false' unless we need need to be able to inspect the generated LLVM
// code as we walk the AST // code as we walk the AST
//mBfIRBuilder->mDbgVerifyCodeGen = true; //mBfIRBuilder->mDbgVerifyCodeGen = true;
if ( if (
(mModuleName == "-") (mModuleName == "-")
//|| (mModuleName == "BeefTest2_ClearColorValue") //|| (mModuleName == "BeefTest2_ClearColorValue")
@ -15160,6 +15160,7 @@ void BfModule::CreateDelegateInvokeMethod()
SizedArray<BfIRType, 8> origParamTypes; SizedArray<BfIRType, 8> origParamTypes;
BfIRType origReturnType; BfIRType origReturnType;
BfIRType staticReturnType;
mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, origParamTypes); mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, origParamTypes);
if (mCurMethodInstance->mReturnType->IsValueType()) if (mCurMethodInstance->mReturnType->IsValueType())
@ -15171,15 +15172,17 @@ void BfModule::CreateDelegateInvokeMethod()
int thisIdx = 0; int thisIdx = 0;
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
{ {
thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1;
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
} }
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx(true) != -1))
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() == 0)) if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() == 0))
memberFuncArgs.push_back(BfIRValue()); // Push 'target' memberFuncArgs.push_back(BfIRValue()); // Push 'target'
mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true); mCurMethodInstance->GetIRFunctionInfo(this, staticReturnType, staticParamTypes, true);
for (int i = 1; i < (int)mCurMethodState->mLocals.size(); i++) for (int i = 1; i < (int)mCurMethodState->mLocals.size(); i++)
{ {
@ -15188,7 +15191,7 @@ void BfModule::CreateDelegateInvokeMethod()
exprEvaluator.PushArg(localVal, memberFuncArgs); exprEvaluator.PushArg(localVal, memberFuncArgs);
} }
auto staticFunc = mBfIRBuilder->CreateFunctionType(origReturnType, staticParamTypes, false); auto staticFunc = mBfIRBuilder->CreateFunctionType(staticReturnType, staticParamTypes, false);
auto staticFuncPtr = mBfIRBuilder->GetPointerTo(staticFunc); auto staticFuncPtr = mBfIRBuilder->GetPointerTo(staticFunc);
auto staticFuncPtrPtr = mBfIRBuilder->GetPointerTo(staticFuncPtr); auto staticFuncPtrPtr = mBfIRBuilder->GetPointerTo(staticFuncPtr);
@ -15233,11 +15236,20 @@ void BfModule::CreateDelegateInvokeMethod()
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr); auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr);
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr); auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs); staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs);
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx(true) != -1))
{ {
// Note: since this is a forced static invocation, we know the sret will be the first parameter // Note: since this is a forced static invocation, we know the sret will be the first parameter
mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet); mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet);
} }
// We had a sret for the non-static but no sret for the static (because we have a lowered return type there)
if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1) && (mCurMethodInstance->GetStructRetIdx(true) == -1))
{
auto sretToType = mBfIRBuilder->GetPointerTo(staticReturnType);
auto sretCastedPtr = mBfIRBuilder->CreateBitCast(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()), sretToType);
mBfIRBuilder->CreateStore(staticResult, sretCastedPtr);
}
if (callingConv == BfIRCallingConv_ThisCall) if (callingConv == BfIRCallingConv_ThisCall)
callingConv = BfIRCallingConv_CDecl; callingConv = BfIRCallingConv_CDecl;
if (callingConv != BfIRCallingConv_CDecl) if (callingConv != BfIRCallingConv_CDecl)

View file

@ -758,7 +758,7 @@ bool BfMethodInstance::HasParamsArray()
int BfMethodInstance::GetStructRetIdx(bool forceStatic) int BfMethodInstance::GetStructRetIdx(bool forceStatic)
{ {
if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType()) && (!mIsIntrinsic)) if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType(NULL, NULL, forceStatic)) && (!mIsIntrinsic))
{ {
auto returnTypeInst = mReturnType->ToTypeInstance(); auto returnTypeInst = mReturnType->ToTypeInstance();
if ((returnTypeInst != NULL) && (returnTypeInst->mHasUnderlyingArray)) if ((returnTypeInst != NULL) && (returnTypeInst->mHasUnderlyingArray))
@ -792,10 +792,11 @@ bool BfMethodInstance::HasSelf()
return false; return false;
} }
bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2) bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2, bool forceStatic)
{ {
// Win32 handler // Win32 handler
if ((mMethodDef->mIsStatic) && (mReturnType->IsComposite()) && if (((mMethodDef->mIsStatic) || (forceStatic)) &&
(mReturnType->IsComposite()) &&
((mReturnType->mSize == 4) || (mReturnType->mSize == 8))) ((mReturnType->mSize == 4) || (mReturnType->mSize == 8)))
{ {
auto returnTypeInst = mReturnType->ToTypeInstance(); auto returnTypeInst = mReturnType->ToTypeInstance();
@ -816,7 +817,7 @@ bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeC
} }
} }
return mReturnType->GetLoweredType(mMethodDef->mIsStatic ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2); return mReturnType->GetLoweredType((mMethodDef->mIsStatic || forceStatic) ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2);
} }
bool BfMethodInstance::WantsStructsAttribByVal() bool BfMethodInstance::WantsStructsAttribByVal()
@ -1179,7 +1180,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
BfTypeCode loweredReturnTypeCode = BfTypeCode_None; BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None; BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2))) if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2, forceStatic)))
{ {
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2); auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
returnType = irReturnType; returnType = irReturnType;

View file

@ -929,7 +929,7 @@ public:
bool HasParamsArray(); bool HasParamsArray();
int GetStructRetIdx(bool forceStatic = false); int GetStructRetIdx(bool forceStatic = false);
bool HasSelf(); bool HasSelf();
bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL); bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL, bool forceStatic = false);
bool WantsStructsAttribByVal(); bool WantsStructsAttribByVal();
bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; } bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; }
bool IsSkipCall(bool bypassVirtual = false); bool IsSkipCall(bool bypassVirtual = false);

View file

@ -114,6 +114,18 @@ namespace Tests
public delegate int DelegateB(T val); public delegate int DelegateB(T val);
} }
[CRepr]
struct Vector3f
{
public float mX;
public float mY;
}
static Vector3f GetVector3f()
{
return .() { mX = 101, mY = 102 };
}
[Test] [Test]
public static void TestBasics() public static void TestBasics()
{ {
@ -167,6 +179,9 @@ namespace Tests
e += new (sender, e) => {}; e += new (sender, e) => {};
e += new => LocalEventHandler; e += new => LocalEventHandler;
e.Dispose(); e.Dispose();
delegate Vector3f() vecDlg = scope => GetVector3f;
Test.Assert(vecDlg().mX == 101);
} }
public static void Modify(ref int a, ref Splattable b) public static void Modify(ref int a, ref Splattable b)