diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 7f0cb2f0..74312632 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -3344,11 +3344,6 @@ void BfIRCodeGen::HandleNextCmd() int intrinId = -1; if (mIntrinsicReverseMap.TryGetValue(funcPtr, &intrinId)) { - if (intrinId == BfIRIntrinsic__PLATFORM) - { - NOP; - } - if (intrinId == BfIRIntrinsic_MemSet) { int align = 1; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 75dc96dd..7afadb26 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1301,7 +1301,9 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) for (auto& methodGroup : typeInst->mMethodInstanceGroups) { 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++; } @@ -1320,7 +1322,8 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) if (!mIsDeleting) Init(); - mOnDemandMethodCount += oldOnDemandCount; + mOnDemandMethodCount += oldOnDemandCount; + VerifyOnDemandMethods(); } 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() { if (mIsConstModule) @@ -9687,12 +9718,14 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || (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 { 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; @@ -9715,7 +9748,7 @@ BfMethodInstance* BfModule::GetRawMethodInstance(BfTypeInstance* typeInstance, B 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) @@ -12724,6 +12757,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM methodInstance->UndoDeclaration(!methodInstance->mIRFunction.IsFake()); doingRedeclare = true; mOnDemandMethodCount++; + VerifyOnDemandMethods(); } } else @@ -12879,8 +12913,14 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM AddMethodToWorkList(methodInstance); } else - { + { 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; } + if ((flags & BfGetMethodInstanceFlag_MethodInstanceOnly) != 0) + { + addToWorkList = false; + } + // if ((flags & BfGetMethodInstanceFlag_NoReference) != 0) // addToWorkList = false; @@ -17793,11 +17838,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) } BfMethodInstance* defaultMethodInstance = methodInstance->mMethodInstanceGroup->mDefault; - - BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet); - + if (!mIsConstModule) { + BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet); + if ((methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) && (methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced)) { @@ -17815,6 +17860,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) } methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced; + VerifyOnDemandMethods(); } } @@ -18057,12 +18103,20 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) BF_ASSERT(unspecializedMethodInstance != methodInstance); if (!unspecializedMethodInstance->mHasBeenProcessed) - { - // Make sure the unspecialized method is processed so we can take its bindings + { + 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 - // Clear mCurMethodState so we don't think we're in a local method - SetAndRestoreValue prevMethodState_Unspec(mCurMethodState, prevMethodState.mPrevVal); - mContext->ProcessMethod(unspecializedMethodInstance); + // Clear mCurMethodState so we don't think we're in a local method + SetAndRestoreValue prevMethodState_Unspec(mCurMethodState, prevMethodState.mPrevVal); + mContext->ProcessMethod(unspecializedMethodInstance); + } } methodState.mGenericTypeBindings = &unspecializedMethodInstance->GetMethodInfoEx()->mGenericTypeBindings; } @@ -22020,17 +22074,25 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); mFuncReferences[methodInstance] = func; } } - + + 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; + if (wasAwaitingDecl) + methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference; + if (addToWorkList) { - bool wasAwaitingDecl = methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl; - if (wasAwaitingDecl) - methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference; - if ((!methodDef->mIsAbstract) && (!methodInstance->mIgnoreBody)) - { - if (!wasAwaitingDecl) - AddMethodToWorkList(methodInstance); + { + AddMethodToWorkList(methodInstance); } else { @@ -22043,6 +22105,10 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); methodInstance->mIRFunction = BfIRFunction(); } } + } + else + { + //BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference); } if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) && diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 4dffb7eb..a7308a44 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1481,6 +1481,7 @@ public: bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType); void SetElementType(BfAstNode* astNode, BfSourceElementType elementType); void SetFail(); + void VerifyOnDemandMethods(); bool IsSkippingExtraResolveChecks(); BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false); BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL); @@ -1852,7 +1853,7 @@ public: BfTypedValue CreateValueFromExpression(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfType* wantTypeRef = NULL, BfEvalExprFlags flags = BfEvalExprFlags_None, BfType** outOrigType = NULL); BfTypedValue CreateValueFromExpression(BfExpression* expr, BfType* wantTypeRef = NULL, BfEvalExprFlags flags = BfEvalExprFlags_None, BfType** outOrigType = NULL); BfTypedValue GetOrCreateVarAddr(BfExpression* expr); - BfMethodInstance* GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL); + BfMethodInstance* GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL); BfMethodInstance* GetRawMethodInstance(BfTypeInstance* typeInstance, BfMethodDef* methodDef); BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false); BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance, bool useUnspecializedType = true); // Unspecialized owner type and unspecialized method type diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index ed4be5a9..1b39618d 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -366,6 +366,11 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter) { + if (checkOuter == NULL) + return true; + if (checkInner == NULL) + return false; + // Added new flags? if ((checkInner->mGenericParamFlags | checkOuter->mGenericParamFlags) != checkOuter->mGenericParamFlags) { @@ -4318,7 +4323,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (!boxedRequired) { if (wantsOnDemandMethods) + { methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference; + mOnDemandMethodCount++; + } continue; } } @@ -4329,7 +4337,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType())) continue; // This is just a placeholder for boxed types - methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; + if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) + methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; if (wantsOnDemandMethods) { @@ -4429,18 +4438,26 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (!implRequired) { - if (!mIsScratchModule) - mOnDemandMethodCount++; + BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet); + if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) + { + if (!mIsScratchModule) + mOnDemandMethodCount++; + } if (!declRequired) { - methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference; + if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) + methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_NoDecl_AwaitingReference; continue; } else { - methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; + if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) + methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; } + + VerifyOnDemandMethods(); } } } @@ -4468,7 +4485,13 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) continue; 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; if (methodInstance == NULL) @@ -4608,13 +4631,15 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (boxedMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) { boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; - if (!mIsScratchModule) - mOnDemandMethodCount++; + VerifyOnDemandMethods(); } } + auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None; + methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly); + auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethod->mMethodDef, BfTypeVector(), - matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None, + methodFlags, matchedMethod->GetForeignType()); auto methodInstance = moduleMethodInstance.mMethodInstance; UniqueSlotVirtualMethod(methodInstance); @@ -4916,7 +4941,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if ((hasDefaultImpl) && (matchedMethod == NULL)) { auto methodDef = bestMethodInst->mMethodDef; - BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_ForeignMethodDef; + BfGetMethodInstanceFlags flags = (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_ForeignMethodDef | BfGetMethodInstanceFlag_MethodInstanceOnly); if ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_UnspecializedPass); auto methodInst = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags, ifaceInst); @@ -4927,7 +4952,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) BfMethodInstance* newMethodInstance = methodInst.mMethodInstance; BF_ASSERT(newMethodInstance->mIsForeignMethodDef); if (newMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) - mOnDemandMethodCount++; + mOnDemandMethodCount++; continue; } } @@ -5006,6 +5031,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } } + VerifyOnDemandMethods(); + ambiguityContext.Finish(); CheckAddFailType(); @@ -5083,6 +5110,8 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) } AddMethodToWorkList(defaultMethod); + // This should put all the specialized methods in the worklist, including us + return; } } @@ -5132,16 +5161,34 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced); if (!mIsScratchModule) - { + { auto onDemandModule = owningModule; if (owningModule->mParentModule != NULL) onDemandModule = owningModule->mParentModule; + + owningModule->VerifyOnDemandMethods(); if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) owningModule->mOnDemandMethodCount++; BF_ASSERT(onDemandModule->mOnDemandMethodCount > 0); + + VerifyOnDemandMethods(); } 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 @@ -9078,11 +9125,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg); genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef); - if (genericArg->IsConstExprValue()) - { - NOP; - } - genericParamIdx++; } diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 2ade984a..12c0c82e 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -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() { auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen; @@ -1164,32 +1181,41 @@ void CeBuilder::Build() auto methodInstance = mCeFunction->mMethodInstance; + if (methodInstance != NULL) { + BfMethodInstance dupMethodInstance; + dupMethodInstance.CopyFrom(methodInstance); auto methodDef = methodInstance->mMethodDef; - BfMethodInstance dupMethodInstance; - dupMethodInstance.CopyFrom(methodInstance); - dupMethodInstance.mIsReified = true; - 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(); + 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) { mCeFunction->mFailed = true; return; - } + } + mBeFunction = (BeFunction*)irCodeGen->GetBeValue(dupMethodInstance.mIRFunction.mId); 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++) { diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index d6bc1731..7b14956e 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -556,6 +556,7 @@ public: 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 EmitSizedOp(CeOp op, const CeOperand& operand, CeOperand* result, bool allowNonStdSize); + void ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance); void Build(); };