mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Allow extending Object and ValueType
This commit is contained in:
parent
0826b6d49f
commit
54dc59e049
6 changed files with 126 additions and 22 deletions
|
@ -42,6 +42,8 @@ BfContext::BfContext(BfCompiler* compiler) :
|
|||
mBfTypeType = NULL;
|
||||
mBfClassVDataPtrType = NULL;
|
||||
mBfObjectType = NULL;
|
||||
mCanSkipObjectCtor = true;
|
||||
mCanSkipValueTypeCtor = true;
|
||||
mMappedObjectRevision = 0;
|
||||
mDeleting = false;
|
||||
mLockModules = false;
|
||||
|
@ -1881,6 +1883,54 @@ void BfContext::UpdateRevisedTypes()
|
|||
BP_ZONE("BfContext::UpdateRevisedTypes");
|
||||
BfLogSysM("BfContext::UpdateRevisedTypes\n");
|
||||
|
||||
auto _CheckCanSkipCtor = [&](BfTypeDef* typeDef)
|
||||
{
|
||||
if (typeDef == NULL)
|
||||
return true;
|
||||
typeDef = typeDef->GetLatest();
|
||||
|
||||
for (auto fieldDef : typeDef->mFields)
|
||||
{
|
||||
if (fieldDef->mIsStatic)
|
||||
continue;
|
||||
if (fieldDef->mInitializer != NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto methodDef : typeDef->mMethods)
|
||||
{
|
||||
if (methodDef->mMethodType == BfMethodType_Init)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto _CheckCanSkipCtorByName = [&](const StringImpl& name)
|
||||
{
|
||||
BfAtomComposite qualifiedFindName;
|
||||
if (!mSystem->ParseAtomComposite(name, qualifiedFindName))
|
||||
return true;
|
||||
auto itr = mSystem->mTypeDefs.TryGet(qualifiedFindName);
|
||||
while (itr)
|
||||
{
|
||||
BfTypeDef* typeDef = *itr;
|
||||
if ((typeDef->mDefState != BfTypeDef::DefState_Deleted) &&
|
||||
(!typeDef->mIsCombinedPartial))
|
||||
{
|
||||
if (typeDef->mFullNameEx == qualifiedFindName)
|
||||
if (!_CheckCanSkipCtor(typeDef))
|
||||
return false;
|
||||
}
|
||||
itr.MoveToNextHashMatch();
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool wantsCanSkipObjectCtor = _CheckCanSkipCtorByName("System.Object");
|
||||
bool wantsCanSkipValueTypeCtor = _CheckCanSkipCtorByName("System.ValueType");
|
||||
|
||||
int wantPtrSize;
|
||||
if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) |
|
||||
(mCompiler->mOptions.mMachineType == BfMachineType_ARM) ||
|
||||
|
@ -1888,10 +1938,13 @@ void BfContext::UpdateRevisedTypes()
|
|||
wantPtrSize = 4;
|
||||
else
|
||||
wantPtrSize = 8;
|
||||
if (wantPtrSize != mSystem->mPtrSize)
|
||||
|
||||
if ((wantPtrSize != mSystem->mPtrSize) || (wantsCanSkipObjectCtor != mCanSkipObjectCtor) || (wantsCanSkipValueTypeCtor != mCanSkipValueTypeCtor))
|
||||
{
|
||||
BfLogSysM("Changing pointer size to: %d\n", wantPtrSize);
|
||||
BfLogSysM("Full rebuild. Pointer: %d CanSkipObjectCtor:%d CanSkipValueTypeCtor:%d\n", wantPtrSize, wantsCanSkipObjectCtor, wantsCanSkipValueTypeCtor);
|
||||
mSystem->mPtrSize = wantPtrSize;
|
||||
mCanSkipObjectCtor = wantsCanSkipObjectCtor;
|
||||
mCanSkipValueTypeCtor = wantsCanSkipValueTypeCtor;
|
||||
auto intPtrType = mScratchModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||
auto uintPtrType = mScratchModule->GetPrimitiveType(BfTypeCode_UIntPtr);
|
||||
if (intPtrType != NULL)
|
||||
|
|
|
@ -384,6 +384,8 @@ public:
|
|||
|
||||
BfTypeInstance* mBfTypeType;
|
||||
BfTypeInstance* mBfObjectType;
|
||||
bool mCanSkipObjectCtor;
|
||||
bool mCanSkipValueTypeCtor;
|
||||
BfPointerType* mBfClassVDataPtrType;
|
||||
|
||||
PtrWorkQueue<BfModule*> mReifyModuleWorkList;
|
||||
|
|
|
@ -6815,7 +6815,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
return BfTypedValue();
|
||||
}
|
||||
|
||||
auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, 1);
|
||||
auto& fieldInstance = arrayType->mBaseType->mFieldInstances[0];
|
||||
auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, fieldInstance.mDataIdx);
|
||||
if (arrayLengthBitCount == 64)
|
||||
mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue64(numElements), addr, 8);
|
||||
else
|
||||
|
@ -13459,6 +13460,10 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|||
mModule->Fail("Invalid delegate type", lambdaBindExpr);
|
||||
return;
|
||||
}
|
||||
mModule->PopulateType(baseDelegateType);
|
||||
|
||||
auto& funcPtrField = baseDelegateType->mFieldInstances[0];
|
||||
auto& targetField = baseDelegateType->mFieldInstances[1];
|
||||
auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType));
|
||||
|
||||
// >> delegate.mTarget = bindResult.mTarget
|
||||
|
@ -13468,7 +13473,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|||
valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(nullPtrType));
|
||||
else
|
||||
valPtr = mModule->GetDefaultValue(nullPtrType);
|
||||
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 2);
|
||||
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, targetField.mDataIdx);
|
||||
mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
|
||||
|
||||
// >> delegate.mFuncPtr = bindResult.mFunc
|
||||
|
@ -13476,7 +13481,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|||
{
|
||||
auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr);
|
||||
auto valPtr = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mClosureFunc, mModule->mBfIRBuilder->MapType(nullPtrType));
|
||||
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 1);
|
||||
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, funcPtrField.mDataIdx);
|
||||
mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr);
|
||||
}
|
||||
|
||||
|
|
|
@ -1562,6 +1562,34 @@ BfIRValue BfModule::CreateStringCharPtr(const StringImpl& str, int stringId, boo
|
|||
return mBfIRBuilder->CreateInBoundsGEP(gv, 0, 0);
|
||||
}
|
||||
|
||||
void BfModule::FixConstValueParams(BfTypeInstance* typeInst, SizedArrayImpl<BfIRValue>& valueParams)
|
||||
{
|
||||
if (!typeInst->mTypeDef->mIsCombinedPartial)
|
||||
return;
|
||||
|
||||
int prevDataIdx = -1;
|
||||
int usedDataIdx = 0;
|
||||
if (typeInst->mBaseType != NULL)
|
||||
usedDataIdx++;
|
||||
|
||||
int startingParamsSize = (int)valueParams.mSize;
|
||||
for (int fieldIdx = 0; fieldIdx < (int)typeInst->mFieldInstances.size(); fieldIdx++)
|
||||
{
|
||||
auto fieldInstance = &typeInst->mFieldInstances[fieldIdx];
|
||||
if (fieldInstance->mDataIdx < 0)
|
||||
continue;
|
||||
|
||||
BF_ASSERT(fieldInstance->mDataIdx > prevDataIdx);
|
||||
prevDataIdx = fieldInstance->mDataIdx;
|
||||
|
||||
usedDataIdx++;
|
||||
if (usedDataIdx <= valueParams.mSize)
|
||||
continue;
|
||||
|
||||
valueParams.Add(GetDefaultValue(fieldInstance->mResolvedType));
|
||||
}
|
||||
}
|
||||
|
||||
BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, bool define)
|
||||
{
|
||||
auto stringTypeInst = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration)->ToTypeInstance();
|
||||
|
@ -1580,12 +1608,14 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId,
|
|||
|
||||
SizedArray<BfIRValue, 8> typeValueParams;
|
||||
GetConstClassValueParam(classVDataGlobal, typeValueParams);
|
||||
FixConstValueParams(stringTypeInst->mBaseType, typeValueParams);
|
||||
auto objData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(stringTypeInst->mBaseType, BfIRPopulateType_Full), typeValueParams);
|
||||
|
||||
auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize;
|
||||
|
||||
typeValueParams.clear();
|
||||
typeValueParams.push_back(objData);
|
||||
|
||||
if (lenByteCount == 4)
|
||||
{
|
||||
typeValueParams.push_back(GetConstValue32((int)str.length())); // mLength
|
||||
|
@ -1597,16 +1627,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId,
|
|||
typeValueParams.push_back(GetConstValue64(0x4000000000000000LL + str.length() + 1)); // mAllocSizeAndFlags
|
||||
}
|
||||
typeValueParams.push_back(stringCharsVal); // mPtr
|
||||
|
||||
for (int fieldIdx = 0; fieldIdx < (int)stringTypeInst->mFieldInstances.size(); fieldIdx++)
|
||||
{
|
||||
auto fieldInstance = &stringTypeInst->mFieldInstances[fieldIdx];
|
||||
if (fieldInstance->mDataIdx < 4)
|
||||
continue;
|
||||
while (fieldInstance->mDataIdx >= typeValueParams.size())
|
||||
typeValueParams.Add(BfIRValue());
|
||||
typeValueParams[fieldInstance->mDataIdx] = GetDefaultValue(fieldInstance->mResolvedType);
|
||||
}
|
||||
FixConstValueParams(stringTypeInst, typeValueParams);
|
||||
|
||||
stringValData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(stringTypeInst, BfIRPopulateType_Full), typeValueParams);
|
||||
}
|
||||
|
@ -5387,6 +5408,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
SizedArray<BfIRValue, 4> typeValueParams;
|
||||
GetConstClassValueParam(typeTypeData, typeValueParams);
|
||||
|
||||
FixConstValueParams(mContext->mBfObjectType, typeValueParams);
|
||||
BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams);
|
||||
|
||||
StringT<128> typeDataName;
|
||||
|
@ -5514,6 +5536,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
GetConstValue(type->mAlign, byteType), // mAlign
|
||||
GetConstValue(stackCount, byteType), // mAllocStackCountOverride
|
||||
};
|
||||
FixConstValueParams(mContext->mBfTypeType, typeDataParams);
|
||||
auto typeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType, BfIRPopulateType_Full), typeDataParams);
|
||||
|
||||
if (typeInstance == NULL)
|
||||
|
@ -5532,6 +5555,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
};
|
||||
|
||||
auto reflectPointerType = ResolveTypeDef(mCompiler->mReflectPointerType)->ToTypeInstance();
|
||||
FixConstValueParams(reflectPointerType, pointerTypeDataParms);
|
||||
auto pointerTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectPointerType, BfIRPopulateType_Full), pointerTypeDataParms);
|
||||
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectPointerType), true,
|
||||
BfIRLinkageType_External, pointerTypeData, typeDataName);
|
||||
|
@ -5549,6 +5573,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
};
|
||||
|
||||
auto reflectRefType = ResolveTypeDef(mCompiler->mReflectRefType)->ToTypeInstance();
|
||||
FixConstValueParams(reflectRefType, refTypeDataParms);
|
||||
auto refTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectRefType, BfIRPopulateType_Full), refTypeDataParms);
|
||||
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectRefType), true,
|
||||
BfIRLinkageType_External, refTypeData, typeDataName);
|
||||
|
@ -5566,6 +5591,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
};
|
||||
|
||||
auto reflectSizedArrayType = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance();
|
||||
FixConstValueParams(reflectSizedArrayType, sizedArrayTypeDataParms);
|
||||
auto sizedArrayTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectSizedArrayType, BfIRPopulateType_Full), sizedArrayTypeDataParms);
|
||||
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectSizedArrayType), true,
|
||||
BfIRLinkageType_External, sizedArrayTypeData, typeDataName);
|
||||
|
@ -5583,6 +5609,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
};
|
||||
|
||||
auto reflectConstExprType = ResolveTypeDef(mCompiler->mReflectConstExprType)->ToTypeInstance();
|
||||
FixConstValueParams(reflectConstExprType, constExprTypeDataParms);
|
||||
auto ConstExprTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectConstExprType, BfIRPopulateType_Full), constExprTypeDataParms);
|
||||
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectConstExprType), true,
|
||||
BfIRLinkageType_External, ConstExprTypeData, typeDataName);
|
||||
|
@ -6450,6 +6477,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
GetConstValue(-1, intType), // mCustomAttributesIdx
|
||||
};
|
||||
}
|
||||
FixConstValueParams(reflectFieldDataType->ToTypeInstance(), payloadFieldVals);
|
||||
auto payloadFieldData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), payloadFieldVals);
|
||||
fieldTypes.push_back(payloadFieldData);
|
||||
}
|
||||
|
@ -7129,6 +7157,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
};
|
||||
|
||||
BfIRType typeInstanceDataType = mBfIRBuilder->MapTypeInst(typeInstanceType->ToTypeInstance(), BfIRPopulateType_Full);
|
||||
FixConstValueParams(typeInstanceType->ToTypeInstance(), typeDataVals);
|
||||
auto typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, typeDataVals);
|
||||
|
||||
if (!needsTypeData)
|
||||
|
@ -14188,6 +14217,19 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
|
|||
return BfTypedValue(globalValue, type, !fieldDef->mIsConst);
|
||||
}
|
||||
|
||||
int BfModule::GetFieldDataIdx(BfTypeInstance* typeInst, int fieldIdx, const char* fieldName)
|
||||
{
|
||||
if (typeInst->IsDataIncomplete())
|
||||
PopulateType(typeInst);
|
||||
if (fieldIdx >= typeInst->mFieldInstances.mSize)
|
||||
{
|
||||
Fail(StrFormat("Invalid field data in type '%s'", TypeToString(typeInst).c_str()));
|
||||
return 0;
|
||||
}
|
||||
auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
|
||||
return fieldInstance.mDataIdx;
|
||||
}
|
||||
|
||||
BfTypedValue BfModule::GetThis()
|
||||
{
|
||||
auto useMethodState = mCurMethodState;
|
||||
|
@ -17158,8 +17200,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
{
|
||||
auto baseType = mCurTypeInstance->mBaseType;
|
||||
if ((!mCurTypeInstance->IsTypedPrimitive()) &&
|
||||
(baseType->mTypeDef != mCompiler->mValueTypeTypeDef) &&
|
||||
(baseType->mTypeDef != mCompiler->mBfObjectTypeDef))
|
||||
((baseType->mTypeDef != mCompiler->mValueTypeTypeDef) || (!mContext->mCanSkipValueTypeCtor)) &&
|
||||
((baseType->mTypeDef != mCompiler->mBfObjectTypeDef) || (!mContext->mCanSkipObjectCtor)))
|
||||
{
|
||||
// Try to find a ctor without any params first
|
||||
BfMethodDef* matchedMethod = NULL;
|
||||
|
|
|
@ -1552,6 +1552,7 @@ public:
|
|||
BfIRValue GetDefaultValue(BfType* type);
|
||||
BfTypedValue GetFakeTypedValue(BfType* type);
|
||||
BfTypedValue GetDefaultTypedValue(BfType* type, bool allowRef = false, BfDefaultValueKind defaultValueKind = BfDefaultValueKind_Const);
|
||||
void FixConstValueParams(BfTypeInstance* typeInst, SizedArrayImpl<BfIRValue>& valueParams);
|
||||
BfIRValue CreateStringObjectValue(const StringImpl& str, int stringId, bool define);
|
||||
BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define);
|
||||
int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
|
||||
|
@ -1668,6 +1669,7 @@ public:
|
|||
void HadSlotCountDependency();
|
||||
BfTypedValue GetCompilerFieldValue(const StringImpl& str);
|
||||
BfTypedValue ReferenceStaticField(BfFieldInstance* fieldInstance);
|
||||
int GetFieldDataIdx(BfTypeInstance* typeInst, int fieldIdx, const char* fieldName = NULL);
|
||||
BfTypedValue GetThis();
|
||||
BfLocalVariable* GetThisVariable();
|
||||
bool IsInGeneric();
|
||||
|
|
|
@ -6580,7 +6580,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto lengthValAddr = mBfIRBuilder->CreateInBoundsGEP(arrayBaseValue, 0, 1);
|
||||
auto lengthValAddr = mBfIRBuilder->CreateInBoundsGEP(arrayBaseValue, 0, GetFieldDataIdx(arrayType->mBaseType, 0, "mLength"));
|
||||
lengthVal = mBfIRBuilder->CreateLoad(lengthValAddr);
|
||||
}
|
||||
lengthVal = mBfIRBuilder->CreateNumericCast(lengthVal, true, BfTypeCode_IntPtr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue