mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Added support for some constant enums with payloads
This commit is contained in:
parent
5677f27cac
commit
86967c39c3
8 changed files with 313 additions and 39 deletions
|
@ -2009,7 +2009,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
int dataSize = 16*1024;
|
int dataSize = 16*1024;
|
||||||
auto irArrType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->MapType(int8Type), dataSize);
|
auto irArrType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->MapType(int8Type), dataSize);
|
||||||
String name = "__BFTLS_EXTRA";
|
String name = "__BFTLS_EXTRA";
|
||||||
auto irVal = bfModule->mBfIRBuilder->CreateGlobalVariable(irArrType, false, BfIRLinkageType_External, bfModule->mBfIRBuilder->CreateConstStructZero(irArrType), name, true);
|
auto irVal = bfModule->mBfIRBuilder->CreateGlobalVariable(irArrType, false, BfIRLinkageType_External, bfModule->mBfIRBuilder->CreateConstAggZero(irArrType), name, true);
|
||||||
BfIRMDNode dbgArrayType = bfModule->mBfIRBuilder->DbgCreateArrayType(dataSize * 8, 8, bfModule->mBfIRBuilder->DbgGetType(int8Type), dataSize);
|
BfIRMDNode dbgArrayType = bfModule->mBfIRBuilder->DbgCreateArrayType(dataSize * 8, 8, bfModule->mBfIRBuilder->DbgGetType(int8Type), dataSize);
|
||||||
bfModule->mBfIRBuilder->DbgCreateGlobalVariable(bfModule->mDICompileUnit, name, name, BfIRMDNode(), 0, dbgArrayType, false, irVal);
|
bfModule->mBfIRBuilder->DbgCreateGlobalVariable(bfModule->mDICompileUnit, name, name, BfIRMDNode(), 0, dbgArrayType, false, irVal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4495,28 +4495,26 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
{
|
{
|
||||||
return BfTypedValue(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), fieldInstance->mOwner);
|
return BfTypedValue(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), fieldInstance->mOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
mModule->PopulateType(fieldInstance->mOwner, BfPopulateType_Data);
|
mModule->PopulateType(fieldInstance->mOwner, BfPopulateType_Data);
|
||||||
// auto agg = mModule->mBfIRBuilder->CreateUndefValue(mModule->mBfIRBuilder->MapType(fieldInstance->mOwner));
|
|
||||||
// agg = mModule->mBfIRBuilder->CreateInsertValue(agg, mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), 2);
|
// OLD:
|
||||||
|
// auto agg = mModule->CreateAlloca(fieldInstance->mOwner);
|
||||||
|
// auto gep = mModule->mBfIRBuilder->CreateInBoundsGEP(agg, 0, 2);
|
||||||
|
// mModule->mBfIRBuilder->CreateStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), gep);
|
||||||
//
|
//
|
||||||
// if (fieldInstance->mResolvedType->mSize != 0)
|
// if (fieldInstance->mResolvedType->mSize != 0)
|
||||||
// {
|
// {
|
||||||
// mModule->FailAfter("Enum case parameters expected", targetSrc);
|
// mModule->FailAfter("Enum case parameters expected", targetSrc);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// return BfTypedValue(agg, fieldInstance->mOwner);
|
// return BfTypedValue(agg, fieldInstance->mOwner, true);
|
||||||
|
|
||||||
auto agg = mModule->CreateAlloca(fieldInstance->mOwner);
|
//NEW
|
||||||
auto gep = mModule->mBfIRBuilder->CreateInBoundsGEP(agg, 0, 2);
|
SizedArray<BfIRValue, 3> values;
|
||||||
mModule->mBfIRBuilder->CreateStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), gep);
|
values.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(curCheckType->mBaseType)));
|
||||||
|
values.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(curCheckType->GetUnionInnerType())));
|
||||||
if (fieldInstance->mResolvedType->mSize != 0)
|
values.Add(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx));
|
||||||
{
|
return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(curCheckType), values), curCheckType);
|
||||||
mModule->FailAfter("Enum case parameters expected", targetSrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BfTypedValue(agg, fieldInstance->mOwner, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldInstance->mConstIdx == -1)
|
if (fieldInstance->mConstIdx == -1)
|
||||||
|
@ -7640,7 +7638,13 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
BfIRValue enumValue;
|
BfIRValue enumValue;
|
||||||
BfTypedValue result;
|
BfTypedValue result;
|
||||||
|
|
||||||
if ((mReceivingValue != NULL) && (mReceivingValue->mType == enumType) && (mReceivingValue->IsAddr()))
|
bool wantConst = IsComptimeEntry();
|
||||||
|
|
||||||
|
if (wantConst)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
else if ((mReceivingValue != NULL) && (mReceivingValue->mType == enumType) && (mReceivingValue->IsAddr()))
|
||||||
{
|
{
|
||||||
result = *mReceivingValue;
|
result = *mReceivingValue;
|
||||||
mReceivingValue = NULL;
|
mReceivingValue = NULL;
|
||||||
|
@ -7657,10 +7661,16 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType;
|
auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType;
|
||||||
mModule->mBfIRBuilder->PopulateType(tupleType);
|
mModule->mBfIRBuilder->PopulateType(tupleType);
|
||||||
|
|
||||||
|
bool constFailed = false;
|
||||||
|
SizedArray<BfIRValue, 8> constTupleMembers;
|
||||||
BfIRValue fieldPtr;
|
BfIRValue fieldPtr;
|
||||||
BfIRValue tuplePtr;
|
BfIRValue tuplePtr;
|
||||||
|
|
||||||
if (!tupleType->IsValuelessType())
|
if (wantConst)
|
||||||
|
{
|
||||||
|
constTupleMembers.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType)));
|
||||||
|
}
|
||||||
|
else if (!tupleType->IsValuelessType())
|
||||||
{
|
{
|
||||||
fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 1);
|
fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 1);
|
||||||
auto tuplePtrType = mModule->CreatePointerType(tupleType);
|
auto tuplePtrType = mModule->CreatePointerType(tupleType);
|
||||||
|
@ -7688,6 +7698,8 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)argValues.mArguments->size()), refNode);
|
BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)argValues.mArguments->size()), refNode);
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
|
||||||
|
if (wantConst)
|
||||||
|
constFailed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7701,12 +7713,21 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
|
|
||||||
auto argValue = ResolveArgValue(argValues.mResolvedArgs[tupleFieldIdx], resolvedFieldType, &receivingValue);
|
auto argValue = ResolveArgValue(argValues.mResolvedArgs[tupleFieldIdx], resolvedFieldType, &receivingValue);
|
||||||
|
|
||||||
|
if (!argValue)
|
||||||
|
{
|
||||||
|
if (wantConst)
|
||||||
|
constFailed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (argValue.IsValuelessType())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Used receiving value?
|
// Used receiving value?
|
||||||
if (argValue.mValue == receivingValue.mValue)
|
if (argValue.mValue == receivingValue.mValue)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((!argValue) || (argValue.IsValuelessType()))
|
|
||||||
continue;
|
|
||||||
argValue = mModule->AggregateSplat(argValue);
|
argValue = mModule->AggregateSplat(argValue);
|
||||||
argValues.mResolvedArgs[tupleFieldIdx].mExpectedType = resolvedFieldType;
|
argValues.mResolvedArgs[tupleFieldIdx].mExpectedType = resolvedFieldType;
|
||||||
if ((argValues.mResolvedArgs[tupleFieldIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt)) != 0)
|
if ((argValues.mResolvedArgs[tupleFieldIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt)) != 0)
|
||||||
|
@ -7721,13 +7742,24 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
// argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple,
|
// argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple,
|
||||||
// but we have a value that needs to be attempted to be casted to void
|
// but we have a value that needs to be attempted to be casted to void
|
||||||
argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType);
|
argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType);
|
||||||
if (tupleFieldPtr)
|
if (wantConst)
|
||||||
|
{
|
||||||
|
if (!argValue.mValue.IsConst())
|
||||||
|
{
|
||||||
|
mModule->Fail("Field not const", argValues.mResolvedArgs[tupleFieldIdx].mExpression);
|
||||||
|
constFailed = true;
|
||||||
|
}
|
||||||
|
constTupleMembers.Add(argValue.mValue);
|
||||||
|
}
|
||||||
|
else if (tupleFieldPtr)
|
||||||
{
|
{
|
||||||
argValue = mModule->LoadValue(argValue);
|
argValue = mModule->LoadValue(argValue);
|
||||||
if (argValue)
|
if (argValue)
|
||||||
mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, tupleFieldPtr, resolvedFieldType->mAlign);
|
mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, tupleFieldPtr, resolvedFieldType->mAlign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (wantConst)
|
||||||
|
constFailed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((intptr)argValues.mResolvedArgs.size() > tupleType->mFieldInstances.size())
|
if ((intptr)argValues.mResolvedArgs.size() > tupleType->mFieldInstances.size())
|
||||||
|
@ -7739,14 +7771,49 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
BfError* error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", argValues.mResolvedArgs.size() - tupleType->mFieldInstances.size()), errorRef);
|
BfError* error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", argValues.mResolvedArgs.size() - tupleType->mFieldInstances.size()), errorRef);
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration);
|
||||||
}
|
|
||||||
|
|
||||||
//auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, 2);
|
if (wantConst)
|
||||||
|
constFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
auto dscrType = enumType->GetDiscriminatorType();
|
auto dscrType = enumType->GetDiscriminatorType();
|
||||||
auto dscrField = &enumType->mFieldInstances.back();
|
auto dscrField = &enumType->mFieldInstances.back();
|
||||||
|
|
||||||
int tagIdx = -fieldInstance->mDataIdx - 1;
|
int tagIdx = -fieldInstance->mDataIdx - 1;
|
||||||
|
|
||||||
|
if ((wantConst) && (!constFailed))
|
||||||
|
{
|
||||||
|
auto unionType = enumType->GetUnionInnerType();
|
||||||
|
auto constTuple = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType, BfIRPopulateType_Full), constTupleMembers);
|
||||||
|
|
||||||
|
Array<uint8> memArr;
|
||||||
|
memArr.Resize(unionType->mSize);
|
||||||
|
if (!mModule->mBfIRBuilder->WriteConstant(constTuple, memArr.mVals, tupleType))
|
||||||
|
{
|
||||||
|
constFailed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto unionValue = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, unionType);
|
||||||
|
if (!unionValue)
|
||||||
|
{
|
||||||
|
constFailed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SizedArray<BfIRValue, 3> constEnumMembers;
|
||||||
|
constEnumMembers.Add(mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(enumType->mBaseType, BfIRPopulateType_Full)));
|
||||||
|
constEnumMembers.Add(unionValue);
|
||||||
|
constEnumMembers.Add(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx));
|
||||||
|
return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(enumType, BfIRPopulateType_Full), constEnumMembers), enumType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constFailed)
|
||||||
|
{
|
||||||
|
return mModule->GetDefaultTypedValue(enumType, false, BfDefaultValueKind_Addr);
|
||||||
|
}
|
||||||
|
|
||||||
auto dscFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, dscrField->mDataIdx);
|
auto dscFieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(enumValue, 0, dscrField->mDataIdx);
|
||||||
mModule->mBfIRBuilder->CreateAlignedStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), dscFieldPtr, 4);
|
mModule->mBfIRBuilder->CreateAlignedStore(mModule->mBfIRBuilder->CreateConst(dscrType->mTypeDef->mTypeCode, tagIdx), dscFieldPtr, 4);
|
||||||
return result;
|
return result;
|
||||||
|
@ -18598,7 +18665,7 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
|
||||||
|
|
||||||
Array<BfIRValue> irValues;
|
Array<BfIRValue> irValues;
|
||||||
irValues.Resize(typedValues.mSize + 1);
|
irValues.Resize(typedValues.mSize + 1);
|
||||||
irValues[0] = mModule->mBfIRBuilder->CreateConstStructZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType));
|
irValues[0] = mModule->mBfIRBuilder->CreateConstAggZero(mModule->mBfIRBuilder->MapType(tupleType->mBaseType));
|
||||||
|
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -664,7 +664,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
||||||
else if (fromConst->mConstType == BfConstType_AggZero)
|
else if (fromConst->mConstType == BfConstType_AggZero)
|
||||||
{
|
{
|
||||||
auto aggZero = (BfConstant*)fromConst;
|
auto aggZero = (BfConstant*)fromConst;
|
||||||
return CreateConstStructZero(fromConst->mIRType);
|
return CreateConstAggZero(fromConst->mIRType);
|
||||||
}
|
}
|
||||||
else if (fromConst->mConstType == BfConstType_Agg)
|
else if (fromConst->mConstType == BfConstType_Agg)
|
||||||
{
|
{
|
||||||
|
@ -747,7 +747,7 @@ BfIRValue BfIRConstHolder::CreateConstNull(BfIRType ptrType)
|
||||||
return irValue;
|
return irValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue BfIRConstHolder::CreateConstStructZero(BfIRType aggType)
|
BfIRValue BfIRConstHolder::CreateConstAggZero(BfIRType aggType)
|
||||||
{
|
{
|
||||||
BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
|
BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
|
||||||
constant->mConstType = BfConstType_AggZero;
|
constant->mConstType = BfConstType_AggZero;
|
||||||
|
@ -863,6 +863,203 @@ BfIRValue BfIRConstHolder::GetUndefConstValue(BfIRType irType)
|
||||||
return undefVal;
|
return undefVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfIRConstHolder::WriteConstant(BfIRValue val, void* ptr, BfType* type)
|
||||||
|
{
|
||||||
|
auto constant = GetConstant(val);
|
||||||
|
if (constant == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (constant->mTypeCode)
|
||||||
|
{
|
||||||
|
case BfTypeCode_Int8:
|
||||||
|
case BfTypeCode_UInt8:
|
||||||
|
case BfTypeCode_Boolean:
|
||||||
|
case BfTypeCode_Char8:
|
||||||
|
*(int8*)ptr = constant->mInt8;
|
||||||
|
return true;
|
||||||
|
case BfTypeCode_Int16:
|
||||||
|
case BfTypeCode_UInt16:
|
||||||
|
case BfTypeCode_Char16:
|
||||||
|
*(int16*)ptr = constant->mInt16;
|
||||||
|
return true;
|
||||||
|
case BfTypeCode_Int32:
|
||||||
|
case BfTypeCode_UInt32:
|
||||||
|
case BfTypeCode_Char32:
|
||||||
|
*(int32*)ptr = constant->mInt32;
|
||||||
|
return true;
|
||||||
|
case BfTypeCode_Int64:
|
||||||
|
case BfTypeCode_UInt64:
|
||||||
|
*(int64*)ptr = constant->mInt64;
|
||||||
|
return true;
|
||||||
|
case BfTypeCode_NullPtr:
|
||||||
|
if (mModule->mSystem->mPtrSize == 4)
|
||||||
|
*(int32*)ptr = 0;
|
||||||
|
else
|
||||||
|
*(int64*)ptr = 0;
|
||||||
|
return true;
|
||||||
|
case BfTypeCode_Float:
|
||||||
|
*(float*)ptr = (float)constant->mDouble;
|
||||||
|
return true;
|
||||||
|
case BfTypeCode_Double:
|
||||||
|
*(double*)ptr = constant->mDouble;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constant->mConstType == BfConstType_Agg)
|
||||||
|
{
|
||||||
|
auto aggConstant = (BfConstantAgg*)constant;
|
||||||
|
if (type->IsSizedArray())
|
||||||
|
{
|
||||||
|
auto sizedArrayType = (BfSizedArrayType*)type;
|
||||||
|
for (int i = 0; i < sizedArrayType->mElementCount; i++)
|
||||||
|
{
|
||||||
|
if (!WriteConstant(aggConstant->mValues[i], (uint8*)ptr + (i * sizedArrayType->mElementType->GetStride()), sizedArrayType->mElementType))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT(type->IsStruct());
|
||||||
|
|
||||||
|
mModule->PopulateType(type);
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (typeInst->mBaseType != NULL)
|
||||||
|
{
|
||||||
|
if (!WriteConstant(aggConstant->mValues[0], ptr, typeInst->mBaseType))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||||
|
{
|
||||||
|
if (fieldInstance.mDataOffset < 0)
|
||||||
|
continue;
|
||||||
|
if (!WriteConstant(aggConstant->mValues[fieldInstance.mDataIdx], (uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constant->mConstType == BfConstType_AggZero)
|
||||||
|
{
|
||||||
|
BF_ASSERT(type->IsComposite());
|
||||||
|
memset(ptr, 0, type->mSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constant->mConstType == BfConstType_BitCast)
|
||||||
|
{
|
||||||
|
auto constBitCast = (BfConstantBitCast*)constant;
|
||||||
|
|
||||||
|
auto constTarget = mModule->mBfIRBuilder->GetConstantById(constBitCast->mTarget);
|
||||||
|
return WriteConstant(BfIRValue(BfIRValueFlags_Const, constBitCast->mTarget), ptr, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type)
|
||||||
|
{
|
||||||
|
if (type->IsPrimitiveType())
|
||||||
|
{
|
||||||
|
auto primType = (BfPrimitiveType*)type;
|
||||||
|
switch (primType->mTypeDef->mTypeCode)
|
||||||
|
{
|
||||||
|
case BfTypeCode_Int8:
|
||||||
|
case BfTypeCode_UInt8:
|
||||||
|
case BfTypeCode_Boolean:
|
||||||
|
case BfTypeCode_Char8:
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr);
|
||||||
|
case BfTypeCode_Int16:
|
||||||
|
case BfTypeCode_UInt16:
|
||||||
|
case BfTypeCode_Char16:
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(int16*)ptr);
|
||||||
|
case BfTypeCode_Int32:
|
||||||
|
case BfTypeCode_UInt32:
|
||||||
|
case BfTypeCode_Char32:
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(int32*)ptr);
|
||||||
|
case BfTypeCode_Int64:
|
||||||
|
case BfTypeCode_UInt64:
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)ptr);
|
||||||
|
case BfTypeCode_NullPtr:
|
||||||
|
return CreateConstNull();
|
||||||
|
case BfTypeCode_Float:
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(float*)ptr);
|
||||||
|
case BfTypeCode_Double:
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(double*)ptr);
|
||||||
|
case BfTypeCode_IntPtr:
|
||||||
|
case BfTypeCode_UIntPtr:
|
||||||
|
if (mModule->mSystem->mPtrSize == 4)
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(int32*)ptr);
|
||||||
|
else
|
||||||
|
return CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)ptr);
|
||||||
|
default:
|
||||||
|
return BfIRValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->IsTypedPrimitive())
|
||||||
|
{
|
||||||
|
return ReadConstant(ptr, type->GetUnderlyingType());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->IsSizedArray())
|
||||||
|
{
|
||||||
|
SizedArray<BfIRValue, 8> irValues;
|
||||||
|
|
||||||
|
auto sizedArrayType = (BfSizedArrayType*)type;
|
||||||
|
for (int i = 0; i < sizedArrayType->mElementCount; i++)
|
||||||
|
{
|
||||||
|
auto val = ReadConstant((uint8*)ptr + (i * sizedArrayType->mElementType->GetStride()), sizedArrayType->mElementType);
|
||||||
|
if (!val)
|
||||||
|
return BfIRValue();
|
||||||
|
irValues.Add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
BfIRType irType;
|
||||||
|
irType.mKind = BfIRTypeData::TypeKind_TypeId;
|
||||||
|
irType.mId = type->mTypeId;
|
||||||
|
return CreateConstAgg(irType, irValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->IsStruct())
|
||||||
|
{
|
||||||
|
mModule->PopulateType(type);
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
SizedArray<BfIRValue, 8> irValues;
|
||||||
|
|
||||||
|
if (typeInst->mBaseType != NULL)
|
||||||
|
{
|
||||||
|
auto val = ReadConstant(ptr, typeInst->mBaseType);
|
||||||
|
if (!val)
|
||||||
|
return BfIRValue();
|
||||||
|
irValues.Add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||||
|
{
|
||||||
|
if (fieldInstance.mDataOffset < 0)
|
||||||
|
continue;
|
||||||
|
auto val = ReadConstant((uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType);
|
||||||
|
if (!val)
|
||||||
|
return BfIRValue();
|
||||||
|
irValues.Add(val);
|
||||||
|
}
|
||||||
|
BfIRType irType;
|
||||||
|
irType.mKind = BfIRTypeData::TypeKind_TypeId;
|
||||||
|
irType.mId = type->mTypeId;
|
||||||
|
return CreateConstAgg(irType, irValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BfIRValue();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void BfIRBuilder::OpFailed()
|
void BfIRBuilder::OpFailed()
|
||||||
|
|
|
@ -928,7 +928,7 @@ public:
|
||||||
BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder);
|
BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder);
|
||||||
BfIRValue CreateConstNull();
|
BfIRValue CreateConstNull();
|
||||||
BfIRValue CreateConstNull(BfIRType nullType);
|
BfIRValue CreateConstNull(BfIRType nullType);
|
||||||
BfIRValue CreateConstStructZero(BfIRType aggType);
|
BfIRValue CreateConstAggZero(BfIRType aggType);
|
||||||
BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values);
|
BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values);
|
||||||
BfIRValue CreateConstAggCE(BfIRType type, addr_ce ptr);
|
BfIRValue CreateConstAggCE(BfIRType type, addr_ce ptr);
|
||||||
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
||||||
|
@ -936,6 +936,9 @@ public:
|
||||||
BfIRValue CreateTypeOf(BfType* type);
|
BfIRValue CreateTypeOf(BfType* type);
|
||||||
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
|
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
|
||||||
BfIRValue GetUndefConstValue(BfIRType type);
|
BfIRValue GetUndefConstValue(BfIRType type);
|
||||||
|
|
||||||
|
bool WriteConstant(BfIRValue val, void* ptr, BfType* type);
|
||||||
|
BfIRValue ReadConstant(void* ptr, BfType* type);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfIRPopulateType
|
enum BfIRPopulateType
|
||||||
|
|
|
@ -1454,7 +1454,7 @@ BfIRValue BfModule::GetDefaultValue(BfType* type)
|
||||||
}
|
}
|
||||||
if (type->IsVoid())
|
if (type->IsVoid())
|
||||||
return mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(type));
|
return mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(type));
|
||||||
return mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(type));
|
return mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue BfModule::GetFakeTypedValue(BfType* type)
|
BfTypedValue BfModule::GetFakeTypedValue(BfType* type)
|
||||||
|
@ -8440,7 +8440,7 @@ BfIRValue BfModule::GetDbgRawAllocData(BfType* type)
|
||||||
}
|
}
|
||||||
|
|
||||||
SizedArray<BfIRValue, 2> dataValues;
|
SizedArray<BfIRValue, 2> dataValues;
|
||||||
dataValues.Add(mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(dbgRawAllocDataType->mBaseType, BfIRPopulateType_Full)));
|
dataValues.Add(mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(dbgRawAllocDataType->mBaseType, BfIRPopulateType_Full)));
|
||||||
dataValues.Add(typeDataRef);
|
dataValues.Add(typeDataRef);
|
||||||
dataValues.Add(markFuncPtr);
|
dataValues.Add(markFuncPtr);
|
||||||
dataValues.Add(mBfIRBuilder->CreateConst(BfTypeCode_Int32, stackCount));
|
dataValues.Add(mBfIRBuilder->CreateConst(BfTypeCode_Int32, stackCount));
|
||||||
|
|
|
@ -11351,7 +11351,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
return allocaInst;
|
return allocaInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto zeroNullable = mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(toType));
|
auto zeroNullable = mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(toType));
|
||||||
return zeroNullable;
|
return zeroNullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11778,7 +11778,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
|
|
||||||
auto stringCharPtr = GetStringCharPtr(stringId);
|
auto stringCharPtr = GetStringCharPtr(stringId);
|
||||||
SizedArray<BfIRValue, 2> spanFieldVals;
|
SizedArray<BfIRValue, 2> spanFieldVals;
|
||||||
spanFieldVals.Add(mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(svTypeInst->mBaseType->mBaseType)));
|
spanFieldVals.Add(mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(svTypeInst->mBaseType->mBaseType)));
|
||||||
spanFieldVals.Add(stringCharPtr);
|
spanFieldVals.Add(stringCharPtr);
|
||||||
spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, entry->mString.mLength));
|
spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, entry->mString.mLength));
|
||||||
|
|
||||||
|
|
|
@ -3368,7 +3368,8 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
||||||
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
|
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
|
||||||
if (fieldConstant == NULL)
|
if (fieldConstant == NULL)
|
||||||
return false;
|
return false;
|
||||||
WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType);
|
if (!WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4)
|
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4)
|
||||||
|
@ -3388,7 +3389,8 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
||||||
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
|
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[i]);
|
||||||
if (fieldConstant == NULL)
|
if (fieldConstant == NULL)
|
||||||
return false;
|
return false;
|
||||||
WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType);
|
if (!WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4)
|
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4)
|
||||||
|
@ -3415,7 +3417,8 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
||||||
if (typeInst->mBaseType != NULL)
|
if (typeInst->mBaseType != NULL)
|
||||||
{
|
{
|
||||||
auto baseConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[0]);
|
auto baseConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[0]);
|
||||||
WriteConstant(module, addr, baseConstant, typeInst->mBaseType);
|
if (!WriteConstant(module, addr, baseConstant, typeInst->mBaseType))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& fieldInstance : typeInst->mFieldInstances)
|
for (auto& fieldInstance : typeInst->mFieldInstances)
|
||||||
|
@ -3426,7 +3429,8 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
||||||
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[fieldInstance.mDataIdx]);
|
auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[fieldInstance.mDataIdx]);
|
||||||
if (fieldConstant == NULL)
|
if (fieldConstant == NULL)
|
||||||
return false;
|
return false;
|
||||||
WriteConstant(module, addr + fieldInstance.mDataOffset, fieldConstant, fieldInstance.mResolvedType);
|
if (!WriteConstant(module, addr + fieldInstance.mDataOffset, fieldConstant, fieldInstance.mResolvedType))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -85,6 +85,9 @@ namespace Tests
|
||||||
}
|
}
|
||||||
Test.Assert(a == 3);
|
Test.Assert(a == 3);
|
||||||
Test.Assert(b == 4);
|
Test.Assert(b == 4);
|
||||||
|
|
||||||
|
const EnumE e0 = .A;
|
||||||
|
const EnumE e1 = .B(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue