1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Delegate comparison expansion, hashable, == operator

This commit is contained in:
Brian Fiete 2022-02-15 09:31:23 -05:00
parent 9dcafb7db8
commit a3a8bfa40c
8 changed files with 157 additions and 18 deletions

View file

@ -3294,7 +3294,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan
BfIRConstHolder* constHolder = typeInstance->mConstHolder;
auto customAttribute = customAttributes->Get(mCompiler->mObsoleteAttributeTypeDef);
if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()))
if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()) && (targetSrc != NULL))
{
String err;
if (methodInstance != NULL)
@ -3349,7 +3349,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan
}
customAttribute = customAttributes->Get(mCompiler->mWarnAttributeTypeDef);
if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()))
if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()) && (targetSrc != NULL))
{
String err;
if (methodInstance != NULL)
@ -4716,6 +4716,87 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
mBfIRBuilder->CreateRetVoid();
}
void BfModule::CreateDelegateEqualsMethod()
{
if (mBfIRBuilder->mIgnoreWrites)
return;
auto refNode = mCurTypeInstance->mTypeDef->GetRefNode();
if (refNode == NULL)
refNode = mCompiler->mValueTypeTypeDef->GetRefNode();
UpdateSrcPos(refNode);
SetIllegalSrcPos();
auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
auto resultVal = CreateAlloca(boolType);
mBfIRBuilder->CreateStore(GetConstValue(0, boolType), resultVal);
auto exitBB = mBfIRBuilder->CreateBlock("exit");
auto delegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
mBfIRBuilder->PopulateType(delegateType);
BfExprEvaluator exprEvaluator(this);
BfTypedValue leftTypedVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[0]);
BfTypedValue lhsDelegate = BfTypedValue(mBfIRBuilder->CreateBitCast(leftTypedVal.mValue, mBfIRBuilder->MapType(delegateType)), delegateType);
BfTypedValue rhsDelegate = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]);
rhsDelegate = LoadValue(rhsDelegate);
BfTypedValue rightTypedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(rhsDelegate.mValue, mBfIRBuilder->MapType(mCurTypeInstance)), mCurTypeInstance);
auto& targetFieldInstance = delegateType->mFieldInstances[0];
BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(lhsDelegate.mValue, 0, targetFieldInstance.mDataIdx), targetFieldInstance.mResolvedType, true);
BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(rhsDelegate.mValue, 0, targetFieldInstance.mDataIdx), targetFieldInstance.mResolvedType, true);
leftValue = LoadValue(leftValue);
rightValue = LoadValue(rightValue);
EmitEquals(leftValue, rightValue, exitBB, false);
bool hadComparison = false;
for (auto& fieldRef : mCurTypeInstance->mFieldInstances)
{
BfFieldInstance* fieldInstance = &fieldRef;
if (fieldInstance->mDataOffset == -1)
continue;
auto fieldType = fieldInstance->mResolvedType;
if (fieldType->IsValuelessType())
continue;
if (fieldType->IsVar())
continue;
if (fieldType->IsMethodRef())
continue;
if (fieldType->IsRef())
fieldType = CreatePointerType(fieldType->GetUnderlyingType());
BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(leftTypedVal.mValue, 0, fieldInstance->mDataIdx), fieldType, true);
BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(rightTypedVal.mValue, 0, fieldInstance->mDataIdx), fieldType, true);
if (!fieldInstance->mResolvedType->IsComposite())
{
leftValue = LoadValue(leftValue);
rightValue = LoadValue(rightValue);
}
EmitEquals(leftValue, rightValue, exitBB, false);
}
mBfIRBuilder->CreateStore(GetConstValue(1, boolType), resultVal);
mBfIRBuilder->CreateBr(exitBB);
mBfIRBuilder->AddBlock(exitBB);
mBfIRBuilder->SetInsertPoint(exitBB);
auto loadedResult = mBfIRBuilder->CreateLoad(resultVal);
ClearLifetimeEnds();
mBfIRBuilder->CreateRet(loadedResult);
mCurMethodState->mHadReturn = true;
}
void BfModule::CreateValueTypeEqualsMethod(bool strictEquals)
{
if (mCurMethodInstance->mIsUnspecialized)
@ -20512,6 +20593,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
skipBody = true;
skipEndChecks = true;
}
else if ((methodDef->mName == BF_METHODNAME_EQUALS) && (mCurTypeInstance->IsDelegate()))
{
CreateDelegateEqualsMethod();
skipBody = true;
skipEndChecks = true;
}
else
{
auto propertyDeclaration = methodDef->GetPropertyDeclaration();