From 88121831e212c16e7b9dbc70896df89c6c1c1882 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 19 Feb 2022 09:46:01 -0500 Subject: [PATCH] Fixed generic interface methods with default impls, comptime attribs --- IDEHelper/Compiler/BfModule.cpp | 59 ++++++++++++++++-------- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 4 +- IDEHelper/Compiler/CeMachine.cpp | 24 +++++++++- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 0ce4c267..5854ce1a 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5489,9 +5489,9 @@ void BfModule::EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx) { - bool isComptime = mBfIRBuilder->mIgnoreWrites; + bool isComptimeArg = mBfIRBuilder->mIgnoreWrites; BfFieldDef* fieldDef = fieldInstance->GetFieldDef(); - + auto typeInstance = fieldInstance->mOwner; BfType* intType = GetPrimitiveType(BfTypeCode_Int32); @@ -5564,7 +5564,7 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt } } - if ((refVal.IsAddr()) && (!isComptime)) + if ((refVal.IsAddr()) && (!isComptimeArg)) constValue = mBfIRBuilder->CreatePtrToInt(refVal.mValue, BfTypeCode_IntPtr); } @@ -5585,10 +5585,10 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt constValue, // mData constValue2, // mDataHi GetConstValue(fieldFlags, shortType), // mFlags - GetConstValue(customAttrIdx, intType), // mCustomAttributesIdx + GetConstValue((isComptimeArg || mIsComptimeModule) ? fieldInstance->mFieldIdx : customAttrIdx, intType), // mCustomAttributesIdx }; - FixConstValueParams(reflectFieldDataType, fieldVals, isComptime); - result = isComptime ? + FixConstValueParams(reflectFieldDataType, fieldVals, isComptimeArg); + result = isComptimeArg ? mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals) : mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals); } @@ -5601,10 +5601,10 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt GetConstValue(typeId, typeIdType), // mFieldTypeId constValue, // mData GetConstValue(fieldFlags, shortType), // mFlags - GetConstValue(customAttrIdx, intType), // mCustomAttributesIdx + GetConstValue((isComptimeArg || mIsComptimeModule) ? fieldInstance->mFieldIdx : customAttrIdx, intType), // mCustomAttributesIdx }; - FixConstValueParams(reflectFieldDataType, fieldVals, isComptime); - result = isComptime ? + FixConstValueParams(reflectFieldDataType, fieldVals, isComptimeArg); + result = isComptimeArg ? mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals) : mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals); } @@ -13732,19 +13732,33 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM break; } } + if (methodInstGroup == NULL) { - // Allocate a new entry - typeInst->mMethodInstanceGroups.Resize(typeInst->mMethodInstanceGroups.size() + 1); - methodInstGroup = &typeInst->mMethodInstanceGroups.back(); - methodInstGroup->mMethodIdx = (int)typeInst->mMethodInstanceGroups.size() - 1; - methodInstGroup->mOwner = typeInst; -// if (methodInstGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) -// methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; - if (mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) - methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; + if (lookupMethodGenericArguments.size() != 0) + { + BF_ASSERT((flags & BfGetMethodInstanceFlag_ForeignMethodDef) != 0); + auto defaultMethodInstance = GetMethodInstance(typeInst, methodDef, BfTypeVector(), + (BfGetMethodInstanceFlags)((flags & (BfGetMethodInstanceFlag_ForeignMethodDef)) | BfGetMethodInstanceFlag_UnspecializedPass | BfGetMethodInstanceFlag_MethodInstanceOnly), foreignType); + methodInstGroup = defaultMethodInstance.mMethodInstance->mMethodInstanceGroup; + } else - methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; + { + // Allocate a new entry + typeInst->mMethodInstanceGroups.Resize(typeInst->mMethodInstanceGroups.size() + 1); + methodInstGroup = &typeInst->mMethodInstanceGroups.back(); + methodInstGroup->mMethodIdx = (int)typeInst->mMethodInstanceGroups.size() - 1; + methodInstGroup->mOwner = typeInst; + // if (methodInstGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) + // methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; + if (mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) + methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; + else + { + methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; + mOnDemandMethodCount++; + } + } } } else @@ -13878,6 +13892,13 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM } else { + if (methodInstGroup->mDefault == NULL) + { + auto defaultMethodInstance = GetMethodInstance(typeInst, methodDef, BfTypeVector(), + (BfGetMethodInstanceFlags)((flags & (BfGetMethodInstanceFlag_ForeignMethodDef)) | BfGetMethodInstanceFlag_UnspecializedPass | BfGetMethodInstanceFlag_MethodInstanceOnly), foreignType); + methodInstGroup = defaultMethodInstance.mMethodInstance->mMethodInstanceGroup; + } + BF_ASSERT(lookupMethodGenericArguments.size() != 0); if (methodInstGroup->mMethodSpecializationMap == NULL) methodInstGroup->mMethodSpecializationMap = new BfMethodInstanceGroup::MapType(); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index d64bd604..52641833 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2239,7 +2239,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* { mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(fieldInfoType->ToTypeInstance()->mBaseType, BfIRPopulateType_Identity)), mBfIRBuilder->CreateTypeOf(mCurTypeInstance), // mTypeInstance - CreateFieldData(fieldInstance, fieldInstance->GetFieldDef()->mIdx) + CreateFieldData(fieldInstance, -1) }; FixConstValueParams(fieldInfoType->ToTypeInstance(), fieldData); auto fieldDataAgg = mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(fieldInfoType, BfIRPopulateType_Identity), fieldData); @@ -12882,7 +12882,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (isNull) { - spanFieldVals.Add(mBfIRBuilder->CreateConstNull()); + spanFieldVals.Add(mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(CreatePointerType(GetPrimitiveType(BfTypeCode_Char8))))); spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0)); } else diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index faadf893..809271ed 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -1297,6 +1297,15 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance dupMethodInstance->mIsReified = true; dupMethodInstance->mInCEMachine = false; // Only have the original one + // We can't use methodInstance->mMethodInstanceGroup because we may add foreign method instances which + // would reallocate the methodInstanceGroup + BfMethodInstanceGroup methodInstanceGroup; + methodInstanceGroup.mOwner = methodInstance->mMethodInstanceGroup->mOwner; + methodInstanceGroup.mDefault = methodInstance->mMethodInstanceGroup->mDefault; + methodInstanceGroup.mMethodIdx = methodInstance->mMethodInstanceGroup->mMethodIdx; + methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; + dupMethodInstance->mMethodInstanceGroup = &methodInstanceGroup; + mCeMachine->mCeModule->mHadBuildError = false; auto irState = irBuilder->GetState(); auto beState = irCodeGen->GetState(); @@ -1306,6 +1315,9 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL) mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete; + + methodInstanceGroup.mDefault = NULL; + dupMethodInstance->mMethodInstanceGroup = methodInstance->mMethodInstanceGroup; } void CeBuilder::Build() @@ -2928,6 +2940,8 @@ CeContext::~CeContext() BfError* CeContext::Fail(const StringImpl& error) { + if (mCurModule == NULL) + return NULL; if (mCurEmitContext != NULL) mCurEmitContext->mFailed = true; auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0); @@ -5126,6 +5140,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto typeInst = type->ToTypeInstance(); if (typeInst != NULL) success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeTypeId, resultPtr); + _FixVariables(); } *(addr_ce*)(stackPtr + 0) = success; @@ -5146,10 +5161,16 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { if (typeInst->mDefineState < BfTypeDefineState_CETypeInit) mCurModule->PopulateType(typeInst); - if (fieldIdx < typeInst->mFieldInstances.mSize) + if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize)) { auto& fieldInstance = typeInst->mFieldInstances[fieldIdx]; success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeTypeId, resultPtr); + _FixVariables(); + } + else if (fieldIdx != -1) + { + _Fail("Invalid field"); + return false; } } } @@ -5169,6 +5190,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return false; } bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeTypeId, resultPtr); + _FixVariables(); *(addr_ce*)(stackPtr + 0) = success; } else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)