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:
parent
8a84647bcd
commit
e1d7939081
11 changed files with 116 additions and 11 deletions
|
@ -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:
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue