mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Fixed StructRet issues with delegates and lambdas
This commit is contained in:
parent
d2edcd2ae9
commit
d5a2db5a06
3 changed files with 67 additions and 20 deletions
|
@ -9542,7 +9542,8 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
{
|
{
|
||||||
hasThis = true;
|
hasThis = true;
|
||||||
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
|
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
|
||||||
irParamTypes[0] = mModule->mBfIRBuilder->MapType(useTypeInstance);
|
int thisIdx = methodInstance->HasStructRet() ? 1 : 0;
|
||||||
|
irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -9558,6 +9559,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
|
auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
|
||||||
funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
|
funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
|
||||||
|
|
||||||
|
if (methodInstance->HasStructRet())
|
||||||
|
{
|
||||||
|
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, 1, BfIRAttribute_NoAlias);
|
||||||
|
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, 1, BfIRAttribute_StructRet);
|
||||||
|
}
|
||||||
|
|
||||||
auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
|
auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
|
||||||
if ((!hasThis) && (methodInstance->mCallingConvention == BfCallingConvention_Stdcall))
|
if ((!hasThis) && (methodInstance->mCallingConvention == BfCallingConvention_Stdcall))
|
||||||
srcCallingConv = BfIRCallingConv_StdCall;
|
srcCallingConv = BfIRCallingConv_StdCall;
|
||||||
|
@ -9571,6 +9578,11 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
|
|
||||||
fieldIdx = 0;
|
fieldIdx = 0;
|
||||||
SizedArray<BfIRValue, 8> irArgs;
|
SizedArray<BfIRValue, 8> irArgs;
|
||||||
|
|
||||||
|
int argIdx = 0;
|
||||||
|
if (methodInstance->HasStructRet())
|
||||||
|
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++));
|
||||||
|
|
||||||
for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
|
for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
|
||||||
{
|
{
|
||||||
auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
|
auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx];
|
||||||
|
@ -9585,13 +9597,16 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
disableSplat = true;
|
disableSplat = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(0), 0, gepIdx);
|
int thisIdx = methodInstance->HasStructRet() ? 1 : 0;
|
||||||
|
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx);
|
||||||
BfTypedValue typedVal(fieldPtr, fieldType, true);
|
BfTypedValue typedVal(fieldPtr, fieldType, true);
|
||||||
PushArg(typedVal, irArgs, disableSplat);
|
PushArg(typedVal, irArgs, disableSplat);
|
||||||
fieldIdx++;
|
fieldIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int argIdx = hasThis ? 1 : 0;
|
if (hasThis)
|
||||||
|
argIdx++;
|
||||||
|
|
||||||
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
|
||||||
{
|
{
|
||||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||||
|
@ -9608,17 +9623,19 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
auto bindFuncVal = bindResult.mFunc;
|
auto bindFuncVal = bindResult.mFunc;
|
||||||
if (mModule->mCompiler->mOptions.mAllowHotSwapping)
|
if (mModule->mCompiler->mOptions.mAllowHotSwapping)
|
||||||
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
|
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
|
||||||
auto result = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
|
auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
|
||||||
|
if (methodInstance->HasStructRet())
|
||||||
|
mModule->mBfIRBuilder->Call_AddAttribute(callInst, 1, BfIRAttribute_StructRet);
|
||||||
auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
|
auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
|
||||||
if (destCallingConv != BfIRCallingConv_CDecl)
|
if (destCallingConv != BfIRCallingConv_CDecl)
|
||||||
mModule->mBfIRBuilder->SetCallCallingConv(result, destCallingConv);
|
mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv);
|
||||||
if (methodInstance->mReturnType->IsValuelessType())
|
if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->HasStructRet()))
|
||||||
{
|
{
|
||||||
mModule->mBfIRBuilder->CreateRetVoid();
|
mModule->mBfIRBuilder->CreateRetVoid();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mModule->mBfIRBuilder->CreateRet(result);
|
mModule->mBfIRBuilder->CreateRet(callInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
|
mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction);
|
||||||
|
@ -10384,13 +10401,9 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
// later then we need to have the mangled names match
|
// later then we need to have the mangled names match
|
||||||
methodDef->mIsStatic = (closureTypeInst == NULL) && (!mModule->mCompiler->mOptions.mAllowHotSwapping);
|
methodDef->mIsStatic = (closureTypeInst == NULL) && (!mModule->mCompiler->mOptions.mAllowHotSwapping);
|
||||||
|
|
||||||
SizedArray<BfIRType, 3> newTypes;
|
|
||||||
SizedArray<BfIRType, 8> origParamTypes;
|
SizedArray<BfIRType, 8> origParamTypes;
|
||||||
BfIRType origReturnType;
|
BfIRType origReturnType;
|
||||||
|
|
||||||
if (!methodDef->mIsStatic)
|
|
||||||
newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
|
|
||||||
|
|
||||||
if (invokeMethodInstance != NULL)
|
if (invokeMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
auto invokeFunctionType = mModule->mBfIRBuilder->MapMethod(invokeMethodInstance);
|
auto invokeFunctionType = mModule->mBfIRBuilder->MapMethod(invokeMethodInstance);
|
||||||
|
@ -10401,7 +10414,19 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
||||||
origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None));
|
origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = methodDef->mIsStatic ? 0 : 1; i < (int)origParamTypes.size(); i++)
|
SizedArray<BfIRType, 3> newTypes;
|
||||||
|
if (invokeMethodInstance->HasStructRet())
|
||||||
|
newTypes.push_back(origParamTypes[0]);
|
||||||
|
if (!methodDef->mIsStatic)
|
||||||
|
newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
|
||||||
|
|
||||||
|
int paramStartIdx = 0;
|
||||||
|
if (invokeMethodInstance->HasStructRet())
|
||||||
|
paramStartIdx++;
|
||||||
|
if (!methodDef->mIsStatic)
|
||||||
|
paramStartIdx++;
|
||||||
|
|
||||||
|
for (int i = paramStartIdx; i < (int)origParamTypes.size(); i++)
|
||||||
newTypes.push_back(origParamTypes[i]);
|
newTypes.push_back(origParamTypes[i]);
|
||||||
auto closureFuncType = mModule->mBfIRBuilder->CreateFunctionType(origReturnType, newTypes, false);
|
auto closureFuncType = mModule->mBfIRBuilder->CreateFunctionType(origReturnType, newTypes, false);
|
||||||
|
|
||||||
|
@ -13195,11 +13220,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
||||||
mModule->Warn(0, "Scope specifier was not referenced in mixin", scopedInvocationTarget->mScopeName);
|
mModule->Warn(0, "Scope specifier was not referenced in mixin", scopedInvocationTarget->mScopeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's tempting to do this, but it is really just covering up other issues.
|
|
||||||
//mModule->mBfIRBuilder->SetCurrentDebugLocation(prevDebugLoc);
|
|
||||||
|
|
||||||
// But does THIS work?
|
|
||||||
mModule->mBfIRBuilder->RestoreDebugLocation();
|
mModule->mBfIRBuilder->RestoreDebugLocation();
|
||||||
|
mModule->mBfIRBuilder->DupDebugLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::SetMethodElementType(BfAstNode* target)
|
void BfExprEvaluator::SetMethodElementType(BfAstNode* target)
|
||||||
|
|
|
@ -1098,7 +1098,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
|
||||||
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||||
if (
|
if (
|
||||||
(mModuleName == "-")
|
(mModuleName == "-")
|
||||||
//|| (mModuleName == "Raylib_Color")
|
//|| (mModuleName == "Blurg")
|
||||||
//|| (mModuleName == "System_Int32")
|
//|| (mModuleName == "System_Int32")
|
||||||
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
||||||
)
|
)
|
||||||
|
@ -13301,6 +13301,8 @@ void BfModule::CreateDelegateInvokeMethod()
|
||||||
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr);
|
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr);
|
||||||
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
|
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
|
||||||
nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs);
|
nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs);
|
||||||
|
if (mCurMethodInstance->HasStructRet())
|
||||||
|
mBfIRBuilder->Call_AddAttribute(nonStaticResult, 1, BfIRAttribute_StructRet);
|
||||||
if (callingConv != BfIRCallingConv_CDecl)
|
if (callingConv != BfIRCallingConv_CDecl)
|
||||||
mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv);
|
mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv);
|
||||||
mCurMethodState->SetHadReturn(false);
|
mCurMethodState->SetHadReturn(false);
|
||||||
|
@ -13317,6 +13319,8 @@ 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 (mCurMethodInstance->HasStructRet())
|
||||||
|
mBfIRBuilder->Call_AddAttribute(staticResult, 1, BfIRAttribute_StructRet);
|
||||||
if (callingConv == BfIRCallingConv_ThisCall)
|
if (callingConv == BfIRCallingConv_ThisCall)
|
||||||
callingConv = BfIRCallingConv_CDecl;
|
callingConv = BfIRCallingConv_CDecl;
|
||||||
if (callingConv != BfIRCallingConv_CDecl)
|
if (callingConv != BfIRCallingConv_CDecl)
|
||||||
|
@ -20021,7 +20025,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
|
|
||||||
if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) &&
|
if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) &&
|
||||||
(!methodDef->mIsLocalMethod) &&
|
(!methodDef->mIsLocalMethod) &&
|
||||||
(!CheckDefineMemberProtection(methodDef->mProtection, methodInstance->mReturnType)))
|
(!CheckDefineMemberProtection(methodDef->mProtection, methodInstance->mReturnType)) &&
|
||||||
|
(!methodDef->mReturnTypeRef->IsTemporary()))
|
||||||
{
|
{
|
||||||
if (methodDef->mMethodType == BfMethodType_PropertyGetter)
|
if (methodDef->mMethodType == BfMethodType_PropertyGetter)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,5 +73,25 @@ namespace Tests
|
||||||
delete dlg;
|
delete dlg;
|
||||||
Test.Assert(b == 221);
|
Test.Assert(b == 221);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructA
|
||||||
|
{
|
||||||
|
public int mA0;
|
||||||
|
public this(int v) { mA0 = v; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestStructRetCapture()
|
||||||
|
{
|
||||||
|
StructA sa = .(5);
|
||||||
|
StructA saGetter() { return sa; }
|
||||||
|
delegate StructA() myTest = scope => saGetter;
|
||||||
|
var ret = myTest();
|
||||||
|
Test.Assert(ret.mA0 == 5);
|
||||||
|
|
||||||
|
delegate StructA() myTest2 = scope [&] () => { return saGetter(); };
|
||||||
|
var ret2 = myTest2();
|
||||||
|
Test.Assert(ret2.mA0 == 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue