1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Improved virtual overrides in extensions

This commit is contained in:
Brian Fiete 2022-05-07 11:40:55 -07:00
parent 8a84647bcd
commit e1d7939081
11 changed files with 116 additions and 11 deletions

View file

@ -2291,6 +2291,14 @@ void BeIRCodeGen::HandleNextCmd()
SetResult(curId, mBeModule->CreateFunction(type, linkageType, name)); SetResult(curId, mBeModule->CreateFunction(type, linkageType, name));
} }
break; break;
case BfIRCmd_SetFunctionName:
{
CMD_PARAM(BeValue*, func);
CMD_PARAM(String, name);
BeFunction* beFunc = BeValueDynCast<BeFunction>(func);
beFunc->mName = name;
}
break;
case BfIRCmd_EnsureFunctionPatchable: case BfIRCmd_EnsureFunctionPatchable:
{ {

View file

@ -5878,6 +5878,23 @@ void BfCompiler::PopulateReified()
checkType = checkType->mBaseType; checkType = checkType->mBaseType;
} }
for (auto& reifyDep : typeInst->mReifyMethodDependencies)
{
if ((reifyDep.mDepMethod.mTypeInstance == NULL) ||
(reifyDep.mDepMethod.mTypeInstance->IsIncomplete()))
continue;
BfMethodInstance* depMethod = reifyDep.mDepMethod;
if (depMethod == NULL)
continue;
if ((depMethod->mIsReified) && (depMethod->mMethodInstanceGroup->IsImplemented()))
{
auto methodDef = typeInst->mTypeDef->mMethods[reifyDep.mMethodIdx];
typeInst->mModule->GetMethodInstance(typeInst, methodDef, BfTypeVector());
}
}
} }
} }
} }

View file

@ -1225,7 +1225,8 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
delete typeInst->mAttributeData; delete typeInst->mAttributeData;
typeInst->mAttributeData = NULL; typeInst->mAttributeData = NULL;
typeInst->mVirtualMethodTableSize = 0; typeInst->mVirtualMethodTableSize = 0;
typeInst->mVirtualMethodTable.Clear(); typeInst->mVirtualMethodTable.Clear();
typeInst->mReifyMethodDependencies.Clear();
typeInst->mSize = -1; typeInst->mSize = -1;
typeInst->mAlign = -1; typeInst->mAlign = -1;
typeInst->mInstSize = -1; typeInst->mInstSize = -1;

View file

@ -5314,6 +5314,12 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT
return retVal; return retVal;
} }
void BfIRBuilder::SetFunctionName(BfIRValue func, const StringImpl& name)
{
WriteCmd(BfIRCmd_SetFunctionName, func, name);
NEW_CMD_INSERTED_IRVALUE;
}
void BfIRBuilder::EnsureFunctionPatchable() void BfIRBuilder::EnsureFunctionPatchable()
{ {
BfIRValue retVal = WriteCmd(BfIRCmd_EnsureFunctionPatchable); BfIRValue retVal = WriteCmd(BfIRCmd_EnsureFunctionPatchable);

View file

@ -278,6 +278,7 @@ enum BfIRCmd : uint8
BfIRCmd_GetIntrinsic, BfIRCmd_GetIntrinsic,
BfIRCmd_CreateFunctionType, BfIRCmd_CreateFunctionType,
BfIRCmd_CreateFunction, BfIRCmd_CreateFunction,
BfIRCmd_SetFunctionName,
BfIRCmd_EnsureFunctionPatchable, BfIRCmd_EnsureFunctionPatchable,
BfIRCmd_RemapBindFunction, BfIRCmd_RemapBindFunction,
BfIRCmd_SetActiveFunction, BfIRCmd_SetActiveFunction,
@ -1305,6 +1306,7 @@ public:
BfIRFunctionType MapMethod(BfMethodInstance* methodInstance); BfIRFunctionType MapMethod(BfMethodInstance* methodInstance);
BfIRFunctionType CreateFunctionType(BfIRType resultType, const BfSizedArray<BfIRType>& paramTypes, bool isVarArg = false); BfIRFunctionType CreateFunctionType(BfIRType resultType, const BfSizedArray<BfIRType>& paramTypes, bool isVarArg = false);
BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name); BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name);
void SetFunctionName(BfIRValue func, const StringImpl& name);
void EnsureFunctionPatchable(); void EnsureFunctionPatchable();
BfIRValue RemapBindFunction(BfIRValue func); BfIRValue RemapBindFunction(BfIRValue func);
void SetActiveFunction(BfIRFunction func); void SetActiveFunction(BfIRFunction func);

View file

@ -2959,7 +2959,7 @@ void BfIRCodeGen::HandleNextCmd()
{ {
CMD_PARAM(llvm::FunctionType*, type); CMD_PARAM(llvm::FunctionType*, type);
BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
CMD_PARAM(String, name); CMD_PARAM(String, name);
auto func = mLLVMModule->getFunction(name.c_str()); auto func = mLLVMModule->getFunction(name.c_str());
if ((func == NULL) || (func->getFunctionType() != type)) if ((func == NULL) || (func->getFunctionType() != type))
@ -2968,6 +2968,14 @@ void BfIRCodeGen::HandleNextCmd()
SetResult(curId, func); SetResult(curId, func);
} }
break; break;
case BfIRCmd_SetFunctionName:
{
CMD_PARAM(llvm::Value*, func);
CMD_PARAM(String, name);
llvm::Function* llvmFunc = llvm::dyn_cast<llvm::Function>(func);
llvmFunc->setName(name.c_str());
}
break;
case BfIRCmd_EnsureFunctionPatchable: case BfIRCmd_EnsureFunctionPatchable:
{ {
int minPatchSize = 5; int minPatchSize = 5;

View file

@ -22547,7 +22547,9 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man
auto checkMethodInstance = mCurTypeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault; auto checkMethodInstance = mCurTypeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault;
if (checkMethodInstance == NULL) if (checkMethodInstance == NULL)
continue; continue;
if ((checkMethodInstance->mIRFunction == prevFunc) && (checkMethodInstance->mMethodDef->mMethodDeclaration != NULL)) if ((checkMethodInstance->mIRFunction == prevFunc) &&
(checkMethodInstance->mMethodDef->mMethodDeclaration != NULL) &&
(checkMethodInstance->mVirtualTableIdx < 0))
{ {
BfAstNode* refNode = methodDef->GetRefNode(); BfAstNode* refNode = methodDef->GetRefNode();
if (auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration()) if (auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration())
@ -24633,12 +24635,38 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
auto declMethodInstance = (BfMethodInstance*)typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod; auto declMethodInstance = (BfMethodInstance*)typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod;
_AddVirtualDecl(declMethodInstance); _AddVirtualDecl(declMethodInstance);
setMethodInstance->mVirtualTableIdx = virtualMethodMatchIdx; setMethodInstance->mVirtualTableIdx = virtualMethodMatchIdx;
auto& implMethodRef = typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod;
if ((!mCompiler->mIsResolveOnly) && (implMethodRef.mMethodNum >= 0) &&
(implMethodRef.mTypeInstance == typeInstance) && (methodInstance->GetOwner() == typeInstance))
{
auto prevImplMethodInstance = (BfMethodInstance*)implMethodRef;
if (prevImplMethodInstance->mMethodDef->mDeclaringType->mProject != methodInstance->mMethodDef->mDeclaringType->mProject)
{
// We may need to have to previous method reified when we must re-slot in another project during vdata creation
BfReifyMethodDependency dep;
dep.mDepMethod = typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod;
dep.mMethodIdx = implMethodRef.mMethodNum;
typeInstance->mReifyMethodDependencies.Add(dep);
}
if (!methodInstance->mMangleWithIdx)
{
// Keep mangled names from conflicting
methodInstance->mMangleWithIdx = true;
if ((methodInstance->mIRFunction) && (methodInstance->mDeclModule->mIsModuleMutable))
{
StringT<4096> mangledName;
BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), methodInstance);
methodInstance->mDeclModule->mBfIRBuilder->SetFunctionName(methodInstance->mIRFunction, mangledName);
}
}
}
typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance; typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance;
} }
} }
if (methodOverriden != NULL) if (methodOverriden != NULL)
{ {
CheckOverridenMethod(methodInstance, methodOverriden); CheckOverridenMethod(methodInstance, methodOverriden);

View file

@ -1903,16 +1903,22 @@ public:
class BfCeTypeInfo; class BfCeTypeInfo;
struct BfReifyMethodDependency
{
public:
BfNonGenericMethodRef mDepMethod;
int mMethodIdx;
};
// Instance of struct or class // Instance of struct or class
class BfTypeInstance : public BfDependedType class BfTypeInstance : public BfDependedType
{ {
public: public:
int mSignatureRevision; int mSignatureRevision;
int mLastNonGenericUsedRevision; int mLastNonGenericUsedRevision;
int mInheritanceId; int mInheritanceId;
int mInheritanceCount; int mInheritanceCount;
BfModule* mModule; BfModule* mModule;
BfTypeDef* mTypeDef; BfTypeDef* mTypeDef;
BfTypeInstance* mBaseType; BfTypeInstance* mBaseType;
BfCustomAttributes* mCustomAttributes; BfCustomAttributes* mCustomAttributes;
@ -1920,12 +1926,12 @@ public:
BfTypeInfoEx* mTypeInfoEx; BfTypeInfoEx* mTypeInfoEx;
BfGenericTypeInfo* mGenericTypeInfo; BfGenericTypeInfo* mGenericTypeInfo;
BfCeTypeInfo* mCeTypeInfo; BfCeTypeInfo* mCeTypeInfo;
Array<BfTypeInterfaceEntry> mInterfaces; Array<BfTypeInterfaceEntry> mInterfaces;
Array<BfTypeInterfaceMethodEntry> mInterfaceMethodTable; Array<BfTypeInterfaceMethodEntry> mInterfaceMethodTable;
Array<BfMethodInstanceGroup> mMethodInstanceGroups; Array<BfMethodInstanceGroup> mMethodInstanceGroups;
Array<BfOperatorInfo*> mOperatorInfo; Array<BfOperatorInfo*> mOperatorInfo;
Array<BfVirtualMethodEntry> mVirtualMethodTable; Array<BfVirtualMethodEntry> mVirtualMethodTable;
Array<BfReifyMethodDependency> mReifyMethodDependencies;
BfHotTypeData* mHotTypeData; BfHotTypeData* mHotTypeData;
int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning) int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning)
Array<BfFieldInstance> mFieldInstances; Array<BfFieldInstance> mFieldInstances;

View file

@ -45,6 +45,19 @@ namespace LibA
T val = default; T val = default;
return Overload0(val); return Overload0(val);
} }
public virtual int GetA()
{
return 1;
}
}
extension LibA0
{
public override int GetA()
{
return 2;
}
} }
struct Handler struct Handler

View file

@ -42,6 +42,10 @@ namespace TestsB
Test.Assert(ca.mB == 1008); Test.Assert(ca.mB == 1008);
Test.Assert(ca.mC == 9); Test.Assert(ca.mC == 9);
Test.Assert(ca.GetVal2() == 11); Test.Assert(ca.GetVal2() == 11);
LibA.LibA0 la0 = scope .();
int la0a = la0.GetA();
Test.Assert(la0a == 2);
} }
} }

View file

@ -57,6 +57,14 @@ extension LibClassA
namespace LibA namespace LibA
{ {
extension LibA0
{
public new override int GetA()
{
return 3;
}
}
extension LibA3 extension LibA3
{ {
this this
@ -386,6 +394,10 @@ namespace Tests
delete ca; delete ca;
Test.Assert(LibClassA.sMagic == 7771); Test.Assert(LibClassA.sMagic == 7771);
LibA.LibA0 la0 = scope .();
int la0a = la0.GetA();
Test.Assert(la0a == 3);
LibA.LibA3 la3 = scope .(); LibA.LibA3 la3 = scope .();
Test.Assert(la3.mA == 114); Test.Assert(la3.mA == 114);
Test.Assert(la3.mB == 7); Test.Assert(la3.mB == 7);