mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 14:24:10 +02:00
Expanded var poisoning for generics
This commit is contained in:
parent
fa3914e674
commit
d8f741e779
3 changed files with 144 additions and 40 deletions
|
@ -156,6 +156,7 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
mActiveTypeDef = NULL;
|
mActiveTypeDef = NULL;
|
||||||
mBestMethodDef = NULL;
|
mBestMethodDef = NULL;
|
||||||
mBackupMethodDef = NULL;
|
mBackupMethodDef = NULL;
|
||||||
|
mBestRawMethodInstance = NULL;
|
||||||
mBestMethodTypeInstance = NULL;
|
mBestMethodTypeInstance = NULL;
|
||||||
mExplicitInterfaceCheck = NULL;
|
mExplicitInterfaceCheck = NULL;
|
||||||
mSelfType = NULL;
|
mSelfType = NULL;
|
||||||
|
@ -169,6 +170,7 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
mAllowNonStatic = true;
|
mAllowNonStatic = true;
|
||||||
mSkipImplicitParams = false;
|
mSkipImplicitParams = false;
|
||||||
mAllowImplicitThis = false;
|
mAllowImplicitThis = false;
|
||||||
|
mHadVarConflictingReturnType = false;
|
||||||
mMethodCheckCount = 0;
|
mMethodCheckCount = 0;
|
||||||
mInferGenericProgressIdx = 0;
|
mInferGenericProgressIdx = 0;
|
||||||
mCheckedKind = BfCheckedKind_NotSet;
|
mCheckedKind = BfCheckedKind_NotSet;
|
||||||
|
@ -178,7 +180,15 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
{
|
{
|
||||||
auto bfType = arg.mTypedValue.mType;
|
auto bfType = arg.mTypedValue.mType;
|
||||||
if (bfType != NULL)
|
if (bfType != NULL)
|
||||||
|
{
|
||||||
mHasVarArguments |= bfType->IsVar();
|
mHasVarArguments |= bfType->IsVar();
|
||||||
|
if (bfType->IsGenericParam())
|
||||||
|
{
|
||||||
|
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)bfType);
|
||||||
|
if ((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
|
||||||
|
mHasVarArguments = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodGenericArguments != NULL)
|
if (methodGenericArguments != NULL)
|
||||||
|
@ -186,8 +196,6 @@ void BfMethodMatcher::Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSized
|
||||||
for (BfTypeReference* genericArg : *methodGenericArguments)
|
for (BfTypeReference* genericArg : *methodGenericArguments)
|
||||||
{
|
{
|
||||||
auto genericArgType = mModule->ResolveTypeRef(genericArg);
|
auto genericArgType = mModule->ResolveTypeRef(genericArg);
|
||||||
// if (genericArgType == NULL)
|
|
||||||
// return;
|
|
||||||
mExplicitMethodGenericArguments.push_back(genericArgType);
|
mExplicitMethodGenericArguments.push_back(genericArgType);
|
||||||
}
|
}
|
||||||
mHadExplicitGenericArguments = true;
|
mHadExplicitGenericArguments = true;
|
||||||
|
@ -213,9 +221,7 @@ bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* de
|
||||||
bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, HashSet<BfType*>& checkedTypeSet)
|
bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, HashSet<BfType*>& checkedTypeSet)
|
||||||
{
|
{
|
||||||
if (argType == NULL)
|
if (argType == NULL)
|
||||||
return false;
|
return false;
|
||||||
if (argType->IsVar())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!wantType->IsUnspecializedType())
|
if (!wantType->IsUnspecializedType())
|
||||||
return true;
|
return true;
|
||||||
|
@ -235,9 +241,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
|
|
||||||
BfType* methodGenericTypeConstraint = NULL;
|
BfType* methodGenericTypeConstraint = NULL;
|
||||||
auto _SetGeneric = [&]()
|
auto _SetGeneric = [&]()
|
||||||
{
|
{
|
||||||
BF_ASSERT((argType == NULL) || (!argType->IsVar()));
|
|
||||||
|
|
||||||
if (argType != NULL)
|
if (argType != NULL)
|
||||||
{
|
{
|
||||||
// Disallow illegal types
|
// Disallow illegal types
|
||||||
|
@ -300,6 +304,12 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
mPrevArgValues[wantGenericParam->mGenericParamIdx] = argValue;
|
mPrevArgValues[wantGenericParam->mGenericParamIdx] = argValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (argType->IsVar())
|
||||||
|
{
|
||||||
|
_SetGeneric();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (wantGenericParam->mGenericParamKind == BfGenericParamKind_Method)
|
if (wantGenericParam->mGenericParamKind == BfGenericParamKind_Method)
|
||||||
{
|
{
|
||||||
auto genericParamInst = methodInstance->mMethodInfoEx->mGenericParams[wantGenericParam->mGenericParamIdx];
|
auto genericParamInst = methodInstance->mMethodInfoEx->mGenericParams[wantGenericParam->mGenericParamIdx];
|
||||||
|
@ -381,8 +391,33 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
if ((wantType->IsGenericTypeInstance()) && (wantType->IsUnspecializedTypeVariation()))
|
if ((wantType->IsGenericTypeInstance()) && (wantType->IsUnspecializedTypeVariation()))
|
||||||
{
|
{
|
||||||
auto wantGenericType = (BfGenericTypeInstance*)wantType;
|
auto wantGenericType = (BfGenericTypeInstance*)wantType;
|
||||||
|
if (argType->IsGenericParam())
|
||||||
|
{
|
||||||
|
auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)argType);
|
||||||
|
if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
|
||||||
|
{
|
||||||
|
InferGenericArgument(methodInstance, mModule->GetPrimitiveType(BfTypeCode_Var), wantType, BfIRValue(), checkedTypeSet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsGenericTypeInstance()))
|
||||||
|
InferGenericArgument(methodInstance, genericParam->mTypeConstraint, wantType, BfIRValue(), checkedTypeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argType->IsVar())
|
||||||
|
{
|
||||||
|
for (int genericArgIdx = 0; genericArgIdx < (int)wantGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
|
{
|
||||||
|
BfType* wantGenericArgument = wantGenericType->mTypeGenericArguments[genericArgIdx];
|
||||||
|
if (!wantGenericArgument->IsUnspecializedType())
|
||||||
|
continue;
|
||||||
|
InferGenericArgument(methodInstance, mModule->GetPrimitiveType(BfTypeCode_Var), wantGenericArgument, BfIRValue(), checkedTypeSet);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!argType->IsGenericTypeInstance())
|
if (!argType->IsGenericTypeInstance())
|
||||||
return true;
|
return true;
|
||||||
auto argGenericType = (BfGenericTypeInstance*)argType;
|
auto argGenericType = (BfGenericTypeInstance*)argType;
|
||||||
if (argGenericType->mTypeDef != wantGenericType->mTypeDef)
|
if (argGenericType->mTypeDef != wantGenericType->mTypeDef)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1555,7 +1590,12 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
// And if neither better nor worse then they are equally good, which is not allowed either
|
// And if neither better nor worse then they are equally good, which is not allowed either
|
||||||
if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse)))
|
if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse)))
|
||||||
{
|
{
|
||||||
if (!mHasVarArguments)
|
if (mHasVarArguments)
|
||||||
|
{
|
||||||
|
if (prevMethodInstance->mReturnType != prevMethodInstance->mReturnType)
|
||||||
|
mHadVarConflictingReturnType = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
BfAmbiguousEntry ambiguousEntry;
|
BfAmbiguousEntry ambiguousEntry;
|
||||||
ambiguousEntry.mMethodInstance = methodInstance;
|
ambiguousEntry.mMethodInstance = methodInstance;
|
||||||
|
@ -1588,6 +1628,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
mAmbiguousEntries.Clear();
|
mAmbiguousEntries.Clear();
|
||||||
hadMatch = true;
|
hadMatch = true;
|
||||||
mBestMethodDef = checkMethod;
|
mBestMethodDef = checkMethod;
|
||||||
|
mBestRawMethodInstance = methodInstance;
|
||||||
|
|
||||||
for (auto& arg : mArguments)
|
for (auto& arg : mArguments)
|
||||||
arg.mBestBoundType = arg.mTypedValue.mType;
|
arg.mBestBoundType = arg.mTypedValue.mType;
|
||||||
|
@ -1646,10 +1687,10 @@ NoMatch:
|
||||||
if (genericArgumentsSubstitute != NULL)
|
if (genericArgumentsSubstitute != NULL)
|
||||||
{
|
{
|
||||||
mBestMethodGenericArguments = *genericArgumentsSubstitute;
|
mBestMethodGenericArguments = *genericArgumentsSubstitute;
|
||||||
#ifdef _DEBUG
|
// #ifdef _DEBUG
|
||||||
for (auto arg : mBestMethodGenericArguments)
|
// for (auto arg : mBestMethodGenericArguments)
|
||||||
BF_ASSERT((arg == NULL) || (!arg->IsVar()));
|
// BF_ASSERT((arg == NULL) || (!arg->IsVar()));
|
||||||
#endif
|
// #endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mBestMethodGenericArguments.clear();
|
mBestMethodGenericArguments.clear();
|
||||||
|
@ -2087,6 +2128,17 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfMethodMatcher::HasVarGenerics()
|
||||||
|
{
|
||||||
|
for (auto genericArg : mBestMethodGenericArguments)
|
||||||
|
if (genericArg->IsVar())
|
||||||
|
return true;
|
||||||
|
for (auto genericArg : mExplicitMethodGenericArguments)
|
||||||
|
if (genericArg->IsVar())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass)
|
void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass)
|
||||||
{
|
{
|
||||||
bool allowPrivate = true;
|
bool allowPrivate = true;
|
||||||
|
@ -7050,20 +7102,29 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
mModule->Fail(StrFormat("Method '%s' does not exist", methodName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Method '%s' does not exist", methodName.c_str()), targetSrc);
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
|
|
||||||
{
|
|
||||||
for (auto& arg : methodMatcher.mBestMethodGenericArguments)
|
|
||||||
{
|
|
||||||
if ((arg != NULL) && (arg->IsVar()))
|
|
||||||
return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((prevBindResult.mPrevVal != NULL) && (methodMatcher.mMethodCheckCount > 1))
|
if ((prevBindResult.mPrevVal != NULL) && (methodMatcher.mMethodCheckCount > 1))
|
||||||
prevBindResult.mPrevVal->mCheckedMultipleMethods = true;
|
prevBindResult.mPrevVal->mCheckedMultipleMethods = true;
|
||||||
|
|
||||||
BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher);
|
BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher);
|
||||||
|
|
||||||
|
if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized))
|
||||||
|
{
|
||||||
|
if (methodMatcher.mHasVarArguments)
|
||||||
|
{
|
||||||
|
BfType* retType = mModule->GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
|
||||||
|
if ((!methodMatcher.mHadVarConflictingReturnType) && (methodMatcher.mBestRawMethodInstance != NULL) && (!methodMatcher.mBestRawMethodInstance->mReturnType->IsUnspecializedTypeVariation()))
|
||||||
|
{
|
||||||
|
if ((!methodMatcher.mBestRawMethodInstance->mReturnType->IsGenericParam()) ||
|
||||||
|
(((BfGenericParamType*)methodMatcher.mBestRawMethodInstance->mReturnType)->mGenericParamKind != BfGenericParamKind_Method))
|
||||||
|
retType = methodMatcher.mBestRawMethodInstance->mReturnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mModule->GetDefaultTypedValue(retType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((bypassVirtual) && (!target.mValue) && (target.mType->IsInterface()))
|
if ((bypassVirtual) && (!target.mValue) && (target.mType->IsInterface()))
|
||||||
{
|
{
|
||||||
target = mModule->GetThis();
|
target = mModule->GetThis();
|
||||||
|
@ -12361,6 +12422,8 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
|
|
||||||
BfMethodInstance* unspecializedMethod = NULL;
|
BfMethodInstance* unspecializedMethod = NULL;
|
||||||
|
|
||||||
|
bool hasVarGenerics = false;
|
||||||
|
|
||||||
for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
|
for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
|
||||||
{
|
{
|
||||||
BfMethodInstance* outerMethodInstance = NULL;
|
BfMethodInstance* outerMethodInstance = NULL;
|
||||||
|
@ -12440,6 +12503,12 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (genericArg->IsVar())
|
||||||
|
{
|
||||||
|
BF_ASSERT(methodMatcher.mHasVarArguments);
|
||||||
|
hasVarGenerics = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (genericArg->IsIntUnknown())
|
if (genericArg->IsIntUnknown())
|
||||||
genericArg = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
genericArg = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
|
|
||||||
|
@ -12448,7 +12517,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
hasDifferentResolvedTypes = true;
|
hasDifferentResolvedTypes = true;
|
||||||
resolvedGenericArguments.push_back(resolvedGenericArg);
|
resolvedGenericArguments.push_back(resolvedGenericArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeInstance* foreignType = NULL;
|
BfTypeInstance* foreignType = NULL;
|
||||||
BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
|
BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None;
|
||||||
|
@ -12479,6 +12548,9 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasVarGenerics)
|
||||||
|
return BfModuleMethodInstance();
|
||||||
|
|
||||||
BfModuleMethodInstance methodInstance;
|
BfModuleMethodInstance methodInstance;
|
||||||
if (methodMatcher.mBestMethodInstance)
|
if (methodMatcher.mBestMethodInstance)
|
||||||
{
|
{
|
||||||
|
@ -12598,21 +12670,24 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty
|
||||||
if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
|
if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
|
||||||
{
|
{
|
||||||
BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, typeInstance, matchedLocalMethod->mMethodDef, methodMatcher);
|
BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, typeInstance, matchedLocalMethod->mMethodDef, methodMatcher);
|
||||||
auto methodInstance = moduleMethodInstance.mMethodInstance;
|
if (moduleMethodInstance)
|
||||||
|
|
||||||
if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState != NULL))
|
|
||||||
{
|
{
|
||||||
// The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its
|
auto methodInstance = moduleMethodInstance.mMethodInstance;
|
||||||
// captures as well
|
|
||||||
if (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId < mModule->mCurMethodState->mClosureState->mCaptureStartAccessId)
|
if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState != NULL))
|
||||||
mModule->mCurMethodState->mClosureState->mCaptureStartAccessId = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (methodInstance->mDisallowCalling) // We need to process the captures from this guy
|
|
||||||
{
|
{
|
||||||
if (mModule->mCurMethodState->mClosureState->mLocalMethodRefSet.Add(methodInstance))
|
// The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its
|
||||||
mModule->mCurMethodState->mClosureState->mLocalMethodRefs.Add(methodInstance);
|
// captures as well
|
||||||
|
if (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId < mModule->mCurMethodState->mClosureState->mCaptureStartAccessId)
|
||||||
|
mModule->mCurMethodState->mClosureState->mCaptureStartAccessId = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (methodInstance->mDisallowCalling) // We need to process the captures from this guy
|
||||||
|
{
|
||||||
|
if (mModule->mCurMethodState->mClosureState->mLocalMethodRefSet.Add(methodInstance))
|
||||||
|
mModule->mCurMethodState->mClosureState->mLocalMethodRefs.Add(methodInstance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,12 +127,13 @@ public:
|
||||||
BfMethodType mMethodType;
|
BfMethodType mMethodType;
|
||||||
BfCheckedKind mCheckedKind;
|
BfCheckedKind mCheckedKind;
|
||||||
bool mHadExplicitGenericArguments;
|
bool mHadExplicitGenericArguments;
|
||||||
bool mHasVarArguments;
|
bool mHasVarArguments;
|
||||||
|
bool mHadVarConflictingReturnType;
|
||||||
bool mBypassVirtual;
|
bool mBypassVirtual;
|
||||||
bool mAllowImplicitThis;
|
bool mAllowImplicitThis;
|
||||||
bool mAllowStatic;
|
bool mAllowStatic;
|
||||||
bool mAllowNonStatic;
|
bool mAllowNonStatic;
|
||||||
bool mSkipImplicitParams;
|
bool mSkipImplicitParams;
|
||||||
int mMethodCheckCount;
|
int mMethodCheckCount;
|
||||||
int mInferGenericProgressIdx;
|
int mInferGenericProgressIdx;
|
||||||
BfType* mExplicitInterfaceCheck;
|
BfType* mExplicitInterfaceCheck;
|
||||||
|
@ -146,6 +147,7 @@ public:
|
||||||
int mBackupArgMatchCount;
|
int mBackupArgMatchCount;
|
||||||
BfMethodDef* mBestMethodDef;
|
BfMethodDef* mBestMethodDef;
|
||||||
BfTypeInstance* mBestMethodTypeInstance;
|
BfTypeInstance* mBestMethodTypeInstance;
|
||||||
|
BfMethodInstance* mBestRawMethodInstance;
|
||||||
BfModuleMethodInstance mBestMethodInstance;
|
BfModuleMethodInstance mBestMethodInstance;
|
||||||
SizedArray<int, 4> mBestMethodGenericArgumentSrcs;
|
SizedArray<int, 4> mBestMethodGenericArgumentSrcs;
|
||||||
BfTypeVector mBestMethodGenericArguments;
|
BfTypeVector mBestMethodGenericArguments;
|
||||||
|
@ -173,6 +175,8 @@ public:
|
||||||
bool WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* methodDef);
|
bool WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* methodDef);
|
||||||
bool CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass);
|
bool CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass);
|
||||||
void TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget = NULL, BfTypedValue* staticResult = NULL);
|
void TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget = NULL, BfTypedValue* staticResult = NULL);
|
||||||
|
bool HasVarGenerics();
|
||||||
|
bool IsVarCall(BfType*& outReturnType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -472,6 +472,11 @@ bool BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
{
|
{
|
||||||
auto genericTypeInstance = (BfGenericTypeInstance*)resolvedTypeRef;
|
auto genericTypeInstance = (BfGenericTypeInstance*)resolvedTypeRef;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (auto genericArg : genericTypeInstance->mTypeGenericArguments)
|
||||||
|
BF_ASSERT(!genericArg->IsVar());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Do it here so the location we attempted to specialize this type will throw the failure if there is one
|
// Do it here so the location we attempted to specialize this type will throw the failure if there is one
|
||||||
if (!BuildGenericParams(resolvedTypeRef))
|
if (!BuildGenericParams(resolvedTypeRef))
|
||||||
return false;
|
return false;
|
||||||
|
@ -5680,6 +5685,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
|
auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (elementType == NULL)
|
if (elementType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (elementType->IsVar())
|
||||||
|
return elementType;
|
||||||
auto sizeType = ResolveGenericType(arrayType->mElementCountSource, typeGenericArguments, methodGenericArguments, allowFail);
|
auto sizeType = ResolveGenericType(arrayType->mElementCountSource, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (sizeType == NULL)
|
if (sizeType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5696,6 +5703,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
|
auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (elementType == NULL)
|
if (elementType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (elementType->IsVar())
|
||||||
|
return elementType;
|
||||||
return CreateSizedArrayType(elementType, (int)arrayType->mElementCount);
|
return CreateSizedArrayType(elementType, (int)arrayType->mElementCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5705,6 +5714,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto elementType = ResolveGenericType(refType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
|
auto elementType = ResolveGenericType(refType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (elementType == NULL)
|
if (elementType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (elementType->IsVar())
|
||||||
|
return elementType;
|
||||||
return CreateRefType(elementType, refType->mRefKind);
|
return CreateRefType(elementType, refType->mRefKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5714,6 +5725,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
|
auto elementType = ResolveGenericType(ptrType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (elementType == NULL)
|
if (elementType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (elementType->IsVar())
|
||||||
|
return elementType;
|
||||||
return CreatePointerType(elementType);
|
return CreatePointerType(elementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5723,6 +5736,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto elementType = ResolveGenericType(arrayType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
|
auto elementType = ResolveGenericType(arrayType->GetUnderlyingType(), typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (elementType == NULL)
|
if (elementType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (elementType->IsVar())
|
||||||
|
return elementType;
|
||||||
return CreateArrayType(elementType, arrayType->mDimensions);
|
return CreateArrayType(elementType, arrayType->mDimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5741,6 +5756,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail);
|
auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (newGenericArg == NULL)
|
if (newGenericArg == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (newGenericArg->IsVar())
|
||||||
|
return newGenericArg;
|
||||||
if (newGenericArg != origGenericArg)
|
if (newGenericArg != origGenericArg)
|
||||||
hadChange = true;
|
hadChange = true;
|
||||||
genericArgs.push_back(newGenericArg);
|
genericArgs.push_back(newGenericArg);
|
||||||
|
@ -5773,6 +5790,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto returnType = ResolveGenericType(unspecializedDelegateInfo->mReturnType, typeGenericArguments, methodGenericArguments, allowFail);
|
auto returnType = ResolveGenericType(unspecializedDelegateInfo->mReturnType, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (returnType == NULL)
|
if (returnType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (returnType->IsVar())
|
||||||
|
return returnType;
|
||||||
_CheckType(returnType);
|
_CheckType(returnType);
|
||||||
if (returnType->IsGenericParam())
|
if (returnType->IsGenericParam())
|
||||||
hasTypeGenerics |= ((BfGenericParamType*)returnType)->mGenericParamKind == BfGenericParamKind_Type;
|
hasTypeGenerics |= ((BfGenericParamType*)returnType)->mGenericParamKind == BfGenericParamKind_Type;
|
||||||
|
@ -5782,6 +5801,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto paramType = ResolveGenericType(param, typeGenericArguments, methodGenericArguments, allowFail);
|
auto paramType = ResolveGenericType(param, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (paramType == NULL)
|
if (paramType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (paramType->IsVar())
|
||||||
|
return paramType;
|
||||||
paramTypes.Add(paramType);
|
paramTypes.Add(paramType);
|
||||||
_CheckType(paramType);
|
_CheckType(paramType);
|
||||||
}
|
}
|
||||||
|
@ -5803,6 +5824,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
|
resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (resolvedArg == NULL)
|
if (resolvedArg == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (resolvedArg->IsVar())
|
||||||
|
return resolvedArg;
|
||||||
}
|
}
|
||||||
genericArgs.push_back(resolvedArg);
|
genericArgs.push_back(resolvedArg);
|
||||||
}
|
}
|
||||||
|
@ -5938,6 +5961,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
auto resolvedArg = ResolveGenericType(genericArg, typeGenericArguments, methodGenericArguments, allowFail);
|
auto resolvedArg = ResolveGenericType(genericArg, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (resolvedArg == NULL)
|
if (resolvedArg == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (resolvedArg->IsVar())
|
||||||
|
return resolvedArg;
|
||||||
genericArgs.push_back(resolvedArg);
|
genericArgs.push_back(resolvedArg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue