1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Fixed on-demand method issues

This commit is contained in:
Brian Fiete 2021-01-05 13:50:57 -08:00
parent e7912b1095
commit d0d89a552e
6 changed files with 189 additions and 58 deletions

View file

@ -3344,11 +3344,6 @@ void BfIRCodeGen::HandleNextCmd()
int intrinId = -1; int intrinId = -1;
if (mIntrinsicReverseMap.TryGetValue(funcPtr, &intrinId)) if (mIntrinsicReverseMap.TryGetValue(funcPtr, &intrinId))
{ {
if (intrinId == BfIRIntrinsic__PLATFORM)
{
NOP;
}
if (intrinId == BfIRIntrinsic_MemSet) if (intrinId == BfIRIntrinsic_MemSet)
{ {
int align = 1; int align = 1;

View file

@ -1301,7 +1301,9 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
for (auto& methodGroup : typeInst->mMethodInstanceGroups) for (auto& methodGroup : typeInst->mMethodInstanceGroups)
{ {
if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) ||
(methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)) (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
(methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) ||
(methodGroup.mOnDemandKind == BfMethodOnDemandKind_InWorkList))
{ {
oldOnDemandCount++; oldOnDemandCount++;
} }
@ -1321,6 +1323,7 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
if (!mIsDeleting) if (!mIsDeleting)
Init(); Init();
mOnDemandMethodCount += oldOnDemandCount; mOnDemandMethodCount += oldOnDemandCount;
VerifyOnDemandMethods();
} }
void BfModule::StartExtension() void BfModule::StartExtension()
@ -2720,6 +2723,34 @@ void BfModule::SetFail()
} }
} }
void BfModule::VerifyOnDemandMethods()
{
#ifdef _DEBUG
// if (mParentModule != NULL)
// {
// BF_ASSERT(mOnDemandMethodCount == 0);
// mParentModule->VerifyOnDemandMethods();
// return;
// }
//
// int onDemandCount = 0;
// for (auto type : mOwnedTypeInstances)
// {
// auto typeInst = type->ToTypeInstance();
// for (auto& methodGroup : typeInst->mMethodInstanceGroups)
// {
// if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) ||
// (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) ||
// (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) ||
// (methodGroup.mOnDemandKind == BfMethodOnDemandKind_InWorkList))
// onDemandCount++;
// }
// }
//
// BF_ASSERT(mOnDemandMethodCount == onDemandCount);
#endif
}
bool BfModule::IsSkippingExtraResolveChecks() bool BfModule::IsSkippingExtraResolveChecks()
{ {
if (mIsConstModule) if (mIsConstModule)
@ -9687,12 +9718,14 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan
if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl)) if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl))
methodGroup.mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; methodGroup.mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
return declModule->GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_UnspecializedPass | BfGetMethodInstanceFlag_Unreified)).mMethodInstance; BfGetMethodInstanceFlags useFlags = (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_MethodInstanceOnly | BfGetMethodInstanceFlag_UnspecializedPass | BfGetMethodInstanceFlag_Unreified);
return declModule->GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), useFlags).mMethodInstance;
} }
else else
{ {
auto declModule = typeInstance->mModule; auto declModule = typeInstance->mModule;
return declModule->GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_UnspecializedPass)).mMethodInstance; BfGetMethodInstanceFlags useFlags = (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_MethodInstanceOnly | BfGetMethodInstanceFlag_UnspecializedPass);
return declModule->GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), useFlags).mMethodInstance;
} }
} }
auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault; auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault;
@ -9715,7 +9748,7 @@ BfMethodInstance* BfModule::GetRawMethodInstance(BfTypeInstance* typeInstance, B
return GetMethodInstance(typeInstance, methodDef, BfTypeVector()).mMethodInstance; return GetMethodInstance(typeInstance, methodDef, BfTypeVector()).mMethodInstance;
} }
return GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx); return GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx, NULL);
} }
BfMethodInstance* BfModule::GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount, bool checkBase, bool allowMixin) BfMethodInstance* BfModule::GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount, bool checkBase, bool allowMixin)
@ -12724,6 +12757,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
methodInstance->UndoDeclaration(!methodInstance->mIRFunction.IsFake()); methodInstance->UndoDeclaration(!methodInstance->mIRFunction.IsFake());
doingRedeclare = true; doingRedeclare = true;
mOnDemandMethodCount++; mOnDemandMethodCount++;
VerifyOnDemandMethods();
} }
} }
else else
@ -12881,6 +12915,12 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
else else
{ {
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced; methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced;
auto owningModule = methodInstance->GetOwner()->mModule;
if (!owningModule->mIsScratchModule)
{
owningModule->mOnDemandMethodCount--;
owningModule->VerifyOnDemandMethods();
}
} }
} }
@ -13140,6 +13180,11 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
addToWorkList = false; addToWorkList = false;
} }
if ((flags & BfGetMethodInstanceFlag_MethodInstanceOnly) != 0)
{
addToWorkList = false;
}
// if ((flags & BfGetMethodInstanceFlag_NoReference) != 0) // if ((flags & BfGetMethodInstanceFlag_NoReference) != 0)
// addToWorkList = false; // addToWorkList = false;
@ -17794,10 +17839,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
BfMethodInstance* defaultMethodInstance = methodInstance->mMethodInstanceGroup->mDefault; BfMethodInstance* defaultMethodInstance = methodInstance->mMethodInstanceGroup->mDefault;
BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
if (!mIsConstModule) if (!mIsConstModule)
{ {
BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
if ((methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) && if ((methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced)) (methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced))
{ {
@ -17815,6 +17860,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
} }
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced; methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced;
VerifyOnDemandMethods();
} }
} }
@ -18057,6 +18103,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
BF_ASSERT(unspecializedMethodInstance != methodInstance); BF_ASSERT(unspecializedMethodInstance != methodInstance);
if (!unspecializedMethodInstance->mHasBeenProcessed) if (!unspecializedMethodInstance->mHasBeenProcessed)
{
if (mIsConstModule)
{
// This will have already been populated by CeMachine
methodState.mGenericTypeBindings = &methodInstance->GetMethodInfoEx()->mGenericTypeBindings;
}
else
{ {
// Make sure the unspecialized method is processed so we can take its bindings // Make sure the unspecialized method is processed so we can take its bindings
@ -18064,6 +18117,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
SetAndRestoreValue<BfMethodState*> prevMethodState_Unspec(mCurMethodState, prevMethodState.mPrevVal); SetAndRestoreValue<BfMethodState*> prevMethodState_Unspec(mCurMethodState, prevMethodState.mPrevVal);
mContext->ProcessMethod(unspecializedMethodInstance); mContext->ProcessMethod(unspecializedMethodInstance);
} }
}
methodState.mGenericTypeBindings = &unspecializedMethodInstance->GetMethodInfoEx()->mGenericTypeBindings; methodState.mGenericTypeBindings = &unspecializedMethodInstance->GetMethodInfoEx()->mGenericTypeBindings;
} }
@ -22021,15 +22075,23 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
} }
} }
if (addToWorkList) if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
{ {
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
auto owningModule = methodInstance->GetOwner()->mModule;
if (!owningModule->mIsScratchModule)
owningModule->mOnDemandMethodCount++;
VerifyOnDemandMethods();
}
bool wasAwaitingDecl = methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl; bool wasAwaitingDecl = methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl;
if (wasAwaitingDecl) if (wasAwaitingDecl)
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference; methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference;
if (addToWorkList)
{
if ((!methodDef->mIsAbstract) && (!methodInstance->mIgnoreBody)) if ((!methodDef->mIsAbstract) && (!methodInstance->mIgnoreBody))
{ {
if (!wasAwaitingDecl)
AddMethodToWorkList(methodInstance); AddMethodToWorkList(methodInstance);
} }
else else
@ -22044,6 +22106,10 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
} }
} }
} }
else
{
//BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference);
}
if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) && if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) &&
(!methodDef->mIsLocalMethod) && (!methodDef->mIsLocalMethod) &&

View file

@ -1481,6 +1481,7 @@ public:
bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType); bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType);
void SetElementType(BfAstNode* astNode, BfSourceElementType elementType); void SetElementType(BfAstNode* astNode, BfSourceElementType elementType);
void SetFail(); void SetFail();
void VerifyOnDemandMethods();
bool IsSkippingExtraResolveChecks(); bool IsSkippingExtraResolveChecks();
BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false); BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false);
BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL); BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);

View file

@ -366,6 +366,11 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan
bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter) bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter)
{ {
if (checkOuter == NULL)
return true;
if (checkInner == NULL)
return false;
// Added new flags? // Added new flags?
if ((checkInner->mGenericParamFlags | checkOuter->mGenericParamFlags) != checkOuter->mGenericParamFlags) if ((checkInner->mGenericParamFlags | checkOuter->mGenericParamFlags) != checkOuter->mGenericParamFlags)
{ {
@ -4318,7 +4323,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
if (!boxedRequired) if (!boxedRequired)
{ {
if (wantsOnDemandMethods) if (wantsOnDemandMethods)
{
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference; methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
mOnDemandMethodCount++;
}
continue; continue;
} }
} }
@ -4329,6 +4337,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType())) if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType()))
continue; // This is just a placeholder for boxed types continue; // This is just a placeholder for boxed types
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude;
if (wantsOnDemandMethods) if (wantsOnDemandMethods)
@ -4428,19 +4437,27 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
} }
if (!implRequired) if (!implRequired)
{
BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet);
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
{ {
if (!mIsScratchModule) if (!mIsScratchModule)
mOnDemandMethodCount++; mOnDemandMethodCount++;
}
if (!declRequired) if (!declRequired)
{ {
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference; methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference;
continue; continue;
} }
else else
{ {
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
} }
VerifyOnDemandMethods();
} }
} }
} }
@ -4468,7 +4485,13 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
continue; continue;
int prevWorklistSize = (int)mContext->mMethodWorkList.size(); int prevWorklistSize = (int)mContext->mMethodWorkList.size();
auto moduleMethodInstance = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None);
auto flags = ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None;
if (methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude)
flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_MethodInstanceOnly);
auto moduleMethodInstance = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags);
auto methodInstance = moduleMethodInstance.mMethodInstance; auto methodInstance = moduleMethodInstance.mMethodInstance;
if (methodInstance == NULL) if (methodInstance == NULL)
@ -4608,13 +4631,15 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
if (boxedMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) if (boxedMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
{ {
boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
if (!mIsScratchModule) VerifyOnDemandMethods();
mOnDemandMethodCount++;
} }
} }
auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethod->mMethodDef, BfTypeVector(), auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethod->mMethodDef, BfTypeVector(),
matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None, methodFlags,
matchedMethod->GetForeignType()); matchedMethod->GetForeignType());
auto methodInstance = moduleMethodInstance.mMethodInstance; auto methodInstance = moduleMethodInstance.mMethodInstance;
UniqueSlotVirtualMethod(methodInstance); UniqueSlotVirtualMethod(methodInstance);
@ -4916,7 +4941,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
if ((hasDefaultImpl) && (matchedMethod == NULL)) if ((hasDefaultImpl) && (matchedMethod == NULL))
{ {
auto methodDef = bestMethodInst->mMethodDef; auto methodDef = bestMethodInst->mMethodDef;
BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_ForeignMethodDef; BfGetMethodInstanceFlags flags = (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_ForeignMethodDef | BfGetMethodInstanceFlag_MethodInstanceOnly);
if ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) if ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType()))
flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_UnspecializedPass); flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_UnspecializedPass);
auto methodInst = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags, ifaceInst); auto methodInst = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags, ifaceInst);
@ -5006,6 +5031,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
} }
} }
VerifyOnDemandMethods();
ambiguityContext.Finish(); ambiguityContext.Finish();
CheckAddFailType(); CheckAddFailType();
@ -5083,6 +5110,8 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance)
} }
AddMethodToWorkList(defaultMethod); AddMethodToWorkList(defaultMethod);
// This should put all the specialized methods in the worklist, including us
return;
} }
} }
@ -5137,11 +5166,29 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance)
if (owningModule->mParentModule != NULL) if (owningModule->mParentModule != NULL)
onDemandModule = owningModule->mParentModule; onDemandModule = owningModule->mParentModule;
owningModule->VerifyOnDemandMethods();
if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet)
owningModule->mOnDemandMethodCount++; owningModule->mOnDemandMethodCount++;
BF_ASSERT(onDemandModule->mOnDemandMethodCount > 0); BF_ASSERT(onDemandModule->mOnDemandMethodCount > 0);
VerifyOnDemandMethods();
} }
methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_InWorkList; methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_InWorkList;
if (methodInstance->mMethodInstanceGroup->mMethodSpecializationMap != NULL)
{
for (auto& kv : *methodInstance->mMethodInstanceGroup->mMethodSpecializationMap)
{
auto specMethodInstance = kv.mValue;
if ((!specMethodInstance->mDeclModule->mIsModuleMutable) && (!specMethodInstance->mDeclModule->mReifyQueued))
{
specMethodInstance->mDeclModule->PrepareForIRWriting(specMethodInstance->GetOwner());
}
specMethodInstance->mDeclModule->AddMethodToWorkList(specMethodInstance);
}
}
} }
} }
else else
@ -9078,11 +9125,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg); genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef); genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
if (genericArg->IsConstExprValue())
{
NOP;
}
genericParamIdx++; genericParamIdx++;
} }

View file

@ -1154,6 +1154,23 @@ void CeBuilder::HandleParams()
} }
} }
void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance)
{
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
auto beModule = irCodeGen->mBeModule;
dupMethodInstance->mIsReified = true;
dupMethodInstance->mInCEMachine = false; // Only have the original one
mCeMachine->mCeModule->mHadBuildError = false;
auto irState = irBuilder->GetState();
auto beState = irCodeGen->GetState();
mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true);
irCodeGen->SetState(beState);
irBuilder->SetState(irState);
}
void CeBuilder::Build() void CeBuilder::Build()
{ {
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen; auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
@ -1164,32 +1181,41 @@ void CeBuilder::Build()
auto methodInstance = mCeFunction->mMethodInstance; auto methodInstance = mCeFunction->mMethodInstance;
if (methodInstance != NULL) if (methodInstance != NULL)
{ {
auto methodDef = methodInstance->mMethodDef;
BfMethodInstance dupMethodInstance; BfMethodInstance dupMethodInstance;
dupMethodInstance.CopyFrom(methodInstance); dupMethodInstance.CopyFrom(methodInstance);
dupMethodInstance.mIsReified = true; auto methodDef = methodInstance->mMethodDef;
dupMethodInstance.mInCEMachine = false; // Only have the original one
bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());
int dependentGenericStartIdx = 0;
if (methodInstance->mMethodInfoEx != NULL)
dependentGenericStartIdx = (int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size();
if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
((methodInstance->GetOwner()->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod))))
{
auto unspecializedMethodInstance = mCeMachine->mCeModule->GetUnspecializedMethodInstance(methodInstance, !methodInstance->mMethodDef->mIsLocalMethod);
if (!unspecializedMethodInstance->mHasBeenProcessed)
{
BfMethodInstance dupUnspecMethodInstance;
dupUnspecMethodInstance.CopyFrom(unspecializedMethodInstance);
ProcessMethod(unspecializedMethodInstance, &dupUnspecMethodInstance);
dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings;
}
}
int startFunctionCount = (int)beModule->mFunctions.size(); int startFunctionCount = (int)beModule->mFunctions.size();
ProcessMethod(methodInstance, &dupMethodInstance);
mCeMachine->mCeModule->mHadBuildError = false;
auto irState = irBuilder->GetState();
auto beState = irCodeGen->GetState();
mCeMachine->mCeModule->ProcessMethod(&dupMethodInstance, true);
irCodeGen->SetState(beState);
irBuilder->SetState(irState);
if (!dupMethodInstance.mIRFunction) if (!dupMethodInstance.mIRFunction)
{ {
mCeFunction->mFailed = true; mCeFunction->mFailed = true;
return; return;
} }
mBeFunction = (BeFunction*)irCodeGen->GetBeValue(dupMethodInstance.mIRFunction.mId);
mIntPtrType = irCodeGen->mBeContext->GetPrimitiveType((mPtrSize == 4) ? BeTypeCode_Int32 : BeTypeCode_Int64); mIntPtrType = irCodeGen->mBeContext->GetPrimitiveType((mPtrSize == 4) ? BeTypeCode_Int32 : BeTypeCode_Int64);
mBeFunction = (BeFunction*)irCodeGen->GetBeValue(dupMethodInstance.mIRFunction.mId);
for (int funcIdx = startFunctionCount; funcIdx < (int)beModule->mFunctions.size(); funcIdx++) for (int funcIdx = startFunctionCount; funcIdx < (int)beModule->mFunctions.size(); funcIdx++)
{ {

View file

@ -556,6 +556,7 @@ public:
void EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeOperand& rhs, CeOperand& result); void EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeOperand& rhs, CeOperand& result);
void EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result); void EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result);
void EmitSizedOp(CeOp op, const CeOperand& operand, CeOperand* result, bool allowNonStdSize); void EmitSizedOp(CeOp op, const CeOperand& operand, CeOperand* result, bool allowNonStdSize);
void ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance);
void Build(); void Build();
}; };