1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Added [?] implied size for sized arrays with initializers

This commit is contained in:
Brian Fiete 2020-06-13 08:36:39 -07:00
parent 82d2963a9e
commit 08e38a03f9
10 changed files with 250 additions and 162 deletions

View file

@ -36,6 +36,38 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
{
// Handle the 'int[?] val = .(1, 2, 3)' case
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
{
if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
{
BfAstNode* initializer = NULL;
int arraySize = -1;
if (mModule->mContext->mCurTypeState != NULL)
{
if (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)
initializer = mModule->mContext->mCurTypeState->mCurFieldDef->mInitializer;
if (mModule->mContext->mCurTypeState->mCurVarInitializer != NULL)
initializer = mModule->mContext->mCurTypeState->mCurVarInitializer;
if (mModule->mContext->mCurTypeState->mArrayInitializerSize != -1)
arraySize = mModule->mContext->mCurTypeState->mArrayInitializerSize;
}
if (initializer != NULL)
{
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(initializer))
arraySize = (int)invocationExpr->mArguments.size();
}
if (arraySize != -1)
{
mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
return mResult;
}
}
}
bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;

View file

@ -15,7 +15,8 @@ enum BfConstResolveFlags
BfConstResolveFlag_ExplicitCast = 1,
BfConstResolveFlag_NoCast = 2,
BfConstResolveFlag_AllowSoftFail = 4,
BfConstResolveFlag_RemapFromStringId = 8
BfConstResolveFlag_RemapFromStringId = 8,
BfConstResolveFlag_ArrayInitSize = 0x10
};
class BfConstResolver : public BfExprEvaluator

View file

@ -116,6 +116,7 @@ public:
ResolveKind_BuildingGenericParams,
ResolveKind_ResolvingVarType,
ResolveKind_UnionInnerType,
ResolveKind_LocalVariable,
};
public:
@ -131,6 +132,8 @@ public:
BfFieldDef* mCurFieldDef;
BfTypeDef* mCurTypeDef;
ResolveKind mResolveKind;
BfAstNode* mCurVarInitializer;
int mArrayInitializerSize;
public:
BfTypeState()
@ -144,6 +147,8 @@ public:
mCurFieldDef = NULL;
mCurAttributeTypeRef = NULL;
mCurTypeDef = NULL;
mCurVarInitializer = NULL;
mArrayInitializerSize = -1;
mResolveKind = ResolveKind_None;
}
@ -158,6 +163,8 @@ public:
mCurFieldDef = NULL;
mCurAttributeTypeRef = NULL;
mCurTypeDef = NULL;
mCurVarInitializer = NULL;
mArrayInitializerSize = -1;
mResolveKind = ResolveKind_None;
}
};

View file

@ -11796,7 +11796,23 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
int writeIdx = 0;
std::function<void(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)> _HandleInitExprs = [&](BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
struct BfInitContext
{
public:
BfModule* mModule;
BfType* resultType;
int dimensions;
SizedArray<BfIRValue, 2>& dimLengthVals;
BfIRValue arraySize;
int& writeIdx;
BfInitContext(BfModule* module, BfType* resultType, int dimensions, SizedArray<BfIRValue, 2>& dimLengthVals, BfIRValue arraySize, int& writeIdx) :
mModule(module), resultType(resultType), dimensions(dimensions), dimLengthVals(dimLengthVals), arraySize(arraySize), writeIdx(writeIdx)
{
}
void Handle(BfIRValue addr, int curDim, const BfSizedArray<BfExpression*>& valueExprs)
{
int exprIdx = 0;
int dimWriteIdx = 0;
@ -11828,17 +11844,17 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
{
if (auto innerTupleExpr = BfNodeDynCast<BfTupleExpression>(initExpr))
{
_HandleInitExprs(addr, curDim + 1, innerTupleExpr->mValues);
Handle(addr, curDim + 1, innerTupleExpr->mValues);
}
else if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(initExpr))
{
SizedArray<BfExpression*, 1> values;
values.Add(parenExpr->mExpression);
_HandleInitExprs(addr, curDim + 1, values);
Handle(addr, curDim + 1, values);
}
else if (auto innerInitExpr = BfNodeDynCast<BfCollectionInitializerExpression>(initExpr))
{
_HandleInitExprs(addr, curDim + 1, innerInitExpr->mValues);
Handle(addr, curDim + 1, innerInitExpr->mValues);
}
dimWriteIdx++;
@ -11957,13 +11973,16 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, isUninit ? 0xCC : 0), clearBytes, resultType->mAlign);
}
}
}
};
BfInitContext initContext(mModule, resultType, dimensions, dimLengthVals, arraySize, writeIdx);
if (resultType->IsVar())
{
SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
mResult = BfTypedValue(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), mModule->GetPrimitiveType(BfTypeCode_Var)));
_HandleInitExprs(mResult.mValue, 0, objCreateExpr->mArguments);
initContext.Handle(mResult.mValue, 0, objCreateExpr->mArguments);
return;
}
@ -11978,7 +11997,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
arrayValue = BfTypedValue(mModule->AllocFromType(resultType, allocTarget, BfIRValue(), arraySize, (int)dimLengthVals.size(), allocFlags, allocTarget.mAlignOverride), ptrType);
}
_HandleInitExprs(arrayValue.mValue, 0, objCreateExpr->mArguments);
initContext.Handle(arrayValue.mValue, 0, objCreateExpr->mArguments);
mResult = arrayValue;
return;
@ -12073,7 +12092,8 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
addr = mModule->mBfIRBuilder->GetFakeVal();
else
addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx);
_HandleInitExprs(addr, 0, objCreateExpr->mArguments);
initContext.Handle(addr, 0, objCreateExpr->mArguments);
return;
}
@ -14370,13 +14390,18 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
int arrSize = 0;
BfTypeState typeState;
typeState.mArrayInitializerSize = (int)invocationExpr->mArguments.size();
SetAndRestoreValue<BfTypeState*> prevTypeState(mModule->mContext->mCurTypeState, &typeState);
if (indexerExpr->mArguments.size() != 0)
{
BfConstResolver constResolver(mModule);
auto arg = indexerExpr->mArguments[0];
constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
if (arg != NULL)
constResolver.Resolve(arg);
constResolver.Resolve(arg, NULL, BfConstResolveFlag_ArrayInitSize);
if (constResolver.mResult.mValue.IsConst())
{

View file

@ -3721,7 +3721,7 @@ bool BfModule::IsThreadLocal(BfFieldInstance * fieldInstance)
return false;
}
BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer, BfFieldDef* fieldDef, BfType* fieldType)
BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer, BfFieldDef* fieldDef, BfType* fieldType, bool doStore)
{
if (fieldDef == NULL)
fieldDef = fieldInstance->GetFieldDef();
@ -3734,6 +3734,8 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
initializer = fieldDef->mInitializer;
}
BfTypedValue staticVarRef;
BfTypedValue result;
if (initializer == NULL)
{
@ -3780,15 +3782,33 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
}
}
BfExprEvaluator exprEvaluator(this);
if (doStore)
{
staticVarRef = ReferenceStaticField(fieldInstance);
exprEvaluator.mReceivingValue = &staticVarRef;
}
if (fieldType->IsVar())
result = CreateValueFromExpression(initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
result = CreateValueFromExpression(exprEvaluator, initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
else
result = CreateValueFromExpression(initializer, fieldType, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
result = CreateValueFromExpression(exprEvaluator, initializer, fieldType, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
if (doStore)
{
if (exprEvaluator.mReceivingValue == NULL)
doStore = false; // Already stored
}
}
if (fieldInstance != NULL)
MarkFieldInitialized(fieldInstance);
if (doStore)
{
result = LoadValue(result);
if (!result.mType->IsValuelessType())
mBfIRBuilder->CreateStore(result.mValue, staticVarRef.mValue);
}
return result;
}
@ -13893,16 +13913,8 @@ void BfModule::CreateStaticCtor()
{
continue;
}
auto assignValue = GetFieldInitializerValue(fieldInst);
if (assignValue)
{
assignValue = LoadValue(assignValue);
if (!assignValue.mType->IsValuelessType())
{
auto staticVarRef = ReferenceStaticField(fieldInst).mValue;
mBfIRBuilder->CreateStore(assignValue.mValue, staticVarRef);
}
}
GetFieldInitializerValue(fieldInst, NULL, NULL, NULL, true);
}
}
}

View file

@ -1609,7 +1609,7 @@ public:
BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL);
void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false);
void ResolveConstField(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field, bool forceResolve = false);
BfTypedValue GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer = NULL, BfFieldDef* fieldDef = NULL, BfType* fieldType = NULL);
BfTypedValue GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer = NULL, BfFieldDef* fieldDef = NULL, BfType* fieldType = NULL, bool doStore = false);
void MarkFieldInitialized(BfFieldInstance* fieldInstance);
bool IsThreadLocal(BfFieldInstance* fieldInstance);
BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field);

View file

@ -7870,7 +7870,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
BfTypedValue typedVal;
{
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
typedVal = constResolver.Resolve(sizeExpr);
typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
}
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
{

View file

@ -2654,7 +2654,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
constResolver.mAllowGenericConstValue = true;
constResolver.mExpectingType = intType;
BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
{
int elemHash = Hash(typedVal.mType, ctx);
@ -3550,7 +3550,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
constResolver.mAllowGenericConstValue = true;
constResolver.mExpectingType = intType;
BfTypedValue typedVal = constResolver.Resolve(sizeExpr);
BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
{
if (!lhs->IsUnknownSizedArray())

View file

@ -1563,6 +1563,10 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
}
else
{
BfTypeState typeState;
typeState.mCurVarInitializer = varDecl->mInitializer;
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
if (unresolvedType == NULL)
unresolvedType = GetPrimitiveType(BfTypeCode_Var);

View file

@ -5,6 +5,7 @@ namespace Tests
class SizedArrays
{
public static int[8] iArr = .(123, 234, 345, );
public static int[?] iArr2 = .(12, 23, 34);
[Test]
static void TestBasics()
@ -24,6 +25,12 @@ namespace Tests
val2[0][0] = 9;
Test.Assert(val0 != val2);
Test.Assert(val2[1] == val1);
int[?] val3 = .(9, 10);
Test.Assert(val3[0] == 9);
var val4 = int[?](11, 12);
Test.Assert(val4[0] == 11);
}
[Test]