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:
parent
5f2d01ac72
commit
401ab0c98e
4 changed files with 40 additions and 12 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue