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

Reworked functions with explicit 'this'

This commit is contained in:
Brian Fiete 2020-09-11 10:33:16 -07:00
parent 9fde8a3c89
commit 3627f8c40f
15 changed files with 556 additions and 199 deletions

View file

@ -768,6 +768,29 @@ bool BfMethodInstance::HasThis()
return (!mMethodInstanceGroup->mOwner->IsValuelessType());
}
BfType* BfMethodInstance::GetThisType()
{
BF_ASSERT(!mMethodDef->mIsStatic);
if (mMethodDef->mHasExplicitThis)
{
auto thisType = mParams[0].mResolvedType;
auto owner = GetOwner();
if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (!thisType->GetLoweredType(BfTypeUsage_Parameter)))
return owner->mModule->CreatePointerType(thisType);
return thisType;
}
return GetParamType(-1);
}
int BfMethodInstance::GetThisIdx()
{
if (mMethodDef->mIsStatic)
return -2;
if (mMethodDef->mHasExplicitThis)
return 0;
return -1;
}
bool BfMethodInstance::HasExplicitThis()
{
if (mMethodDef->mIsStatic)
@ -827,17 +850,18 @@ String BfMethodInstance::GetParamName(int paramIdx)
}
BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
{
{
if (paramIdx == -1)
{
if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL))
return mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
BF_ASSERT(!mMethodDef->mIsStatic);
auto owner = mMethodInstanceGroup->mOwner;
auto delegateInfo = owner->GetDelegateInfo();
BfType* thisType = owner;
if ((delegateInfo != NULL) && (delegateInfo->mFunctionThisType != NULL))
thisType = delegateInfo->mFunctionThisType;
if (owner->IsFunction())
{
BF_FATAL("Wrong 'this' index");
}
if ((thisType->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (!thisType->GetLoweredType(BfTypeUsage_Parameter)))
return owner->mModule->CreatePointerType(thisType);
return thisType;
@ -1034,8 +1058,10 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
returnType = module->mBfIRBuilder->MapType(mReturnType);
}
for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++)
{
{
BfType* checkType = NULL;
if (paramIdx == -1)
{
@ -1048,7 +1074,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
else
{
if (HasExplicitThis())
checkType = GetParamType(-1);
checkType = GetParamType(0);
else
checkType = GetOwner();
}
@ -1102,14 +1128,14 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
}
}
if ((paramIdx == 0) && (GetParamName(0) == "this") && (checkType->IsPointer()))
{
// We don't actually pass a this pointer for mut methods in valueless structs
auto underlyingType = checkType->GetUnderlyingType();
module->PopulateType(underlyingType, BfPopulateType_Data);
if (underlyingType->IsValuelessType())
continue;
}
// if ((paramIdx == 0) && (GetParamName(0) == "this") && (checkType->IsPointer()))
// {
// // We don't actually pass a this pointer for mut methods in valueless structs
// auto underlyingType = checkType->GetUnderlyingType();
// module->PopulateType(underlyingType, BfPopulateType_Data);
// if (underlyingType->IsValuelessType())
// continue;
// }
if (checkType->CanBeValuelessType())
module->PopulateType(checkType, BfPopulateType_Data);
@ -1159,6 +1185,9 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
if (checkType2 != NULL)
_AddType(checkType2);
if ((paramIdx == -1) && (mMethodDef->mHasExplicitThis))
paramIdx++; // Skip over the explicit 'this'
}
if (GetStructRetIdx(forceStatic) == 1)
@ -1200,7 +1229,7 @@ bool BfMethodInstance::IsExactMatch(BfMethodInstance* other, bool ignoreImplicit
if (checkThis)
{
if (other->mMethodDef->mIsStatic != mMethodDef->mIsStatic)
return false;
return false;
// {
// // If we are static and we have to match a non-static method, allow us to do so if we have an explicitly defined 'this' param that matches
@ -1227,13 +1256,18 @@ bool BfMethodInstance::IsExactMatch(BfMethodInstance* other, bool ignoreImplicit
if (!mMethodDef->mIsStatic)
{
if (GetParamType(-1) != other->GetParamType(-1))
if (GetThisType() != other->GetThisType())
{
return false;
}
}
}
if (mMethodDef->mHasExplicitThis)
implicitParamCountA++;
if (other->mMethodDef->mHasExplicitThis)
implicitParamCountB++;
if (GetParamCount() - implicitParamCountA != other->GetParamCount() - implicitParamCountB)
return false;
for (int i = 0; i < (int)GetParamCount() - implicitParamCountA; i++)
@ -2577,14 +2611,6 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
BF_ASSERT(methodDef->mName == "Invoke");
BF_ASSERT(delegateInfo->mParams.size() == methodDef->mParams.size());
if (delegateInfo->mFunctionThisType != NULL)
{
hashVal = ((hashVal ^ (Hash(delegateInfo->mFunctionThisType, ctx))) << 5) - hashVal;
String paramName = "this";
int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
}
for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++)
{
// Parse attributes?
@ -3300,6 +3326,10 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
auto lhsMethodDef = lhsInst->mTypeDef->mMethods[0];
auto rhsMethodDef = rhsInst->mTypeDef->mMethods[0];
if (lhsMethodDef->mCallingConvention != rhsMethodDef->mCallingConvention)
return false;
if (lhsMethodDef->mIsMutating != rhsMethodDef->mIsMutating)
return false;
if (lhsDelegateInfo->mReturnType != rhsDelegateInfo->mReturnType)
return false;
if (lhsDelegateInfo->mParams.size() != rhsDelegateInfo->mParams.size())
@ -3701,44 +3731,42 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
auto param0 = rhsDelegateType->mParams[0];
if ((param0->mNameNode != NULL) && (param0->mNameNode->Equals("this")))
{
if (!lhsDelegateInfo->mHasExplicitThis)
return false;
bool handled = false;
auto lhsThisType = lhsDelegateInfo->mFunctionThisType;
auto lhsThisType = lhsDelegateInfo->mParams[0];
auto rhsThisType = ctx->mModule->ResolveTypeRef(param0->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoWarnOnMut | BfResolveTypeRefFlag_AllowRef));
bool wantsMutating = false;
if (rhsThisType->IsRef())
{
if (lhsThisType != rhsThisType->GetUnderlyingType())
return false;
if (!invokeMethodDef->mIsMutating)
return false;
wantsMutating = (lhsThisType->IsValueType()) || (lhsThisType->IsGenericParam());
}
else
{
if (lhsThisType != rhsThisType)
return false;
if ((invokeMethodDef->mIsMutating) && (lhsThisType->IsValueType()))
return false;
return false;
}
if (invokeMethodDef->mIsMutating != wantsMutating)
return false;
paramRefOfs = 1;
}
}
if (!rhsIsDelegate)
{
if ((lhsDelegateInfo->mFunctionThisType == NULL) != (paramRefOfs == 0))
return false;
}
if (lhsDelegateInfo->mParams.size() != (int)rhsDelegateType->mParams.size() - paramRefOfs)
if (lhsDelegateInfo->mParams.size() != (int)rhsDelegateType->mParams.size())
return false;
for (int paramIdx = 0; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++)
for (int paramIdx = paramRefOfs; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++)
{
if (!Equals(lhsDelegateInfo->mParams[paramIdx], rhsDelegateType->mParams[paramIdx + paramRefOfs]->mTypeRef, ctx))
if (!Equals(lhsDelegateInfo->mParams[paramIdx], rhsDelegateType->mParams[paramIdx]->mTypeRef, ctx))
return false;
StringView rhsParamName;
if (rhsDelegateType->mParams[paramIdx + paramRefOfs]->mNameNode != NULL)
rhsParamName = rhsDelegateType->mParams[paramIdx + paramRefOfs]->mNameNode->ToStringView();
if (rhsDelegateType->mParams[paramIdx]->mNameNode != NULL)
rhsParamName = rhsDelegateType->mParams[paramIdx]->mNameNode->ToStringView();
if (invokeMethodDef->mParams[paramIdx]->mName != rhsParamName)
return false;
}