mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Improved boxed value support in attribute data
This commit is contained in:
parent
2dcc9552e2
commit
a34e5a737d
10 changed files with 222 additions and 9 deletions
|
@ -167,7 +167,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
}
|
||||
else
|
||||
{
|
||||
mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None)));
|
||||
mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_WantsConst | BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
|
|||
|
||||
if (argExpr != NULL)
|
||||
{
|
||||
argValue = mModule->Cast(argExpr, argValue, wantType);
|
||||
argValue = mModule->Cast(argExpr, argValue, wantType, (BfCastFlags)(BfCastFlags_WantsConst | BfCastFlags_NoConversionOperator));
|
||||
if (!argValue)
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -963,7 +963,17 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
ptrToInt->mToType = fromPtrToInt->mToType;
|
||||
copiedConst = (BfConstant*)ptrToInt;
|
||||
}
|
||||
|
||||
else if (fromConst->mConstType == BfConstType_Box)
|
||||
{
|
||||
auto fromBox = (BfConstantBox*)fromConst;
|
||||
auto fromTarget = fromHolder->GetConstantById(fromBox->mTarget);
|
||||
auto copiedTarget = CreateConst(fromTarget, fromHolder);
|
||||
auto box = mTempAlloc.Alloc<BfConstantBox>();
|
||||
box->mConstType = BfConstType_Box;
|
||||
box->mTarget = copiedTarget.mId;
|
||||
box->mToType = fromBox->mToType;
|
||||
copiedConst = (BfConstant*)box;
|
||||
}
|
||||
else
|
||||
{
|
||||
BF_FATAL("not handled");
|
||||
|
|
|
@ -5729,6 +5729,49 @@ void BfModule::EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType
|
|||
for (int i = 0; i < argType->mSize; i++)
|
||||
data.Add(0);
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_Box)
|
||||
{
|
||||
auto box = (BfConstantBox*)constant;
|
||||
PUSH_INT32(box->mToType.mId);
|
||||
|
||||
BfType* resultType = NULL;
|
||||
if (box->mToType.mKind == BfIRTypeData::TypeKind_TypeId)
|
||||
resultType = mContext->FindTypeById(box->mToType.mId);
|
||||
|
||||
if ((resultType != NULL) && (resultType->IsBoxed()))
|
||||
{
|
||||
auto boxedType = (BfBoxedType*)resultType;
|
||||
|
||||
int dataOffset = 0;
|
||||
if (!boxedType->mFieldInstances.IsEmpty())
|
||||
dataOffset = BF_MAX(boxedType->mFieldInstances.back().mDataOffset, 0);
|
||||
|
||||
int dataSize = boxedType->mInstSize - dataOffset;
|
||||
for (int i = 0; i < dataSize; i++)
|
||||
data.Add(0);
|
||||
|
||||
typeInstance->mConstHolder->WriteConstant(BfIRValue(BfIRValueFlags_Const, box->mTarget), &data[data.mSize - dataSize], boxedType->GetUnderlyingType());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//int dataOffset =
|
||||
|
||||
//mBfIRBuilder->WriteConstant()
|
||||
|
||||
// BfType* resultType = NULL;
|
||||
// if (box->mToType.mKind == BfIRTypeData::TypeKind_TypeId)
|
||||
// resultType = mContext->FindTypeById(box->mToType.mId);
|
||||
//
|
||||
// if ((resultType != NULL) && (resultType->IsBoxed()))
|
||||
// {
|
||||
// auto boxedType = (BfBoxedType*)resultType;
|
||||
// EncodeAttributeData(typeInstance, boxedType->GetUnderlyingType(), BfIRValue(BfIRValueFlags_Const, box->mTarget), data, usedStringIdMap);
|
||||
// return;
|
||||
// }
|
||||
|
||||
Fail(StrFormat("Unhandled constant box in '%s'", TypeToString(typeInstance).c_str()));
|
||||
}
|
||||
|
||||
// else if (constant->mConstType == BfConstType_Agg)
|
||||
// {
|
||||
|
@ -5995,6 +6038,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
{
|
||||
BF_ASSERT((type->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted) || mIsComptimeModule);
|
||||
typeCode = typeInstance->mTypeDef->mTypeCode;
|
||||
if (typeInstance->IsBoxed())
|
||||
typeCode = BfTypeCode_Object;
|
||||
}
|
||||
else if (type->IsPrimitiveType())
|
||||
{
|
||||
|
@ -11639,7 +11684,7 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal)
|
|||
{
|
||||
auto bitcast = (BfConstantBitCast*)constant;
|
||||
BfIRValue newVal;
|
||||
if (bitcast->mTarget)
|
||||
if (constant->mConstType == BfConstType_BitCast)
|
||||
{
|
||||
newVal = BfIRValue(BfIRValueFlags_Const, bitcast->mTarget);
|
||||
CurrentAddToConstHolder(newVal);
|
||||
|
@ -11782,12 +11827,13 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
|||
{
|
||||
if (!allowUnactualized)
|
||||
{
|
||||
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
|
||||
if ((wantType == NULL) ||
|
||||
(wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
|
||||
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
|
||||
{
|
||||
const StringImpl& str = mContext->mStringObjectIdMap[constant->mInt32].mString;
|
||||
BfIRValue stringObjConst = GetStringObjectValue(str, false, true);
|
||||
if (wantType->IsPointer())
|
||||
if ((wantType != NULL) && (wantType->IsPointer()))
|
||||
return GetStringCharPtr(stringObjConst, true);
|
||||
return stringObjConst;
|
||||
}
|
||||
|
|
|
@ -4817,6 +4817,47 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
return module->CreateTypeDataRef(module->mContext->mTypes[typeId]);
|
||||
}
|
||||
|
||||
if (typeInst == module->mContext->mBfObjectType)
|
||||
{
|
||||
// Allow boxing
|
||||
CE_CREATECONST_CHECKPTR(instData, ceModule->mSystem->mPtrSize);
|
||||
addr_ce typeId = *(int*)(instData);
|
||||
|
||||
BfType* type = GetBfType(typeId);
|
||||
|
||||
if (type->IsInstanceOf(mCeMachine->mCompiler->mStringTypeDef))
|
||||
{
|
||||
return CreateConstant(module, ptr, type, outType);
|
||||
}
|
||||
else if (type->IsBoxed())
|
||||
{
|
||||
auto underlyingType = type->GetUnderlyingType();
|
||||
module->PopulateType(type);
|
||||
|
||||
auto boxedType = (BfBoxedType*)type;
|
||||
int dataOffset = boxedType->mFieldInstances.back().mDataOffset;
|
||||
|
||||
auto origValue = CreateConstant(module, ptr + dataOffset, underlyingType, outType);
|
||||
if (origValue)
|
||||
{
|
||||
if (outType != NULL)
|
||||
*outType = typeInst;
|
||||
return irBuilder->CreateConstBox(origValue, irBuilder->MapType(boxedType));
|
||||
}
|
||||
}
|
||||
|
||||
// else if (type->IsValueType())
|
||||
// {
|
||||
// auto origValue = CreateConstant(module, ptr, type, outType);
|
||||
// if (origValue)
|
||||
// {
|
||||
// auto boxedType = module->CreateBoxedType(type);
|
||||
// irBuilder->PopulateType(boxedType);
|
||||
// return irBuilder->CreateConstBox(origValue, irBuilder->MapType(boxedType));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if (typeInst->IsObjectOrInterface())
|
||||
{
|
||||
Fail(StrFormat("Reference type '%s' return value not allowed", module->TypeToString(typeInst).c_str()));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue