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) 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 explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
bool noCast = (flags & BfConstResolveFlag_NoCast) != 0; bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0; bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;

View file

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

View file

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

View file

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

View file

@ -3721,7 +3721,7 @@ bool BfModule::IsThreadLocal(BfFieldInstance * fieldInstance)
return false; 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) if (fieldDef == NULL)
fieldDef = fieldInstance->GetFieldDef(); fieldDef = fieldInstance->GetFieldDef();
@ -3734,6 +3734,8 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
initializer = fieldDef->mInitializer; initializer = fieldDef->mInitializer;
} }
BfTypedValue staticVarRef;
BfTypedValue result; BfTypedValue result;
if (initializer == NULL) 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()) if (fieldType->IsVar())
result = CreateValueFromExpression(initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer)); result = CreateValueFromExpression(exprEvaluator, initializer, NULL, (BfEvalExprFlags)(BfEvalExprFlags_NoValueAddr | BfEvalExprFlags_FieldInitializer));
else 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) if (fieldInstance != NULL)
MarkFieldInitialized(fieldInstance); MarkFieldInitialized(fieldInstance);
if (doStore)
{
result = LoadValue(result);
if (!result.mType->IsValuelessType())
mBfIRBuilder->CreateStore(result.mValue, staticVarRef.mValue);
}
return result; return result;
} }
@ -13893,16 +13913,8 @@ void BfModule::CreateStaticCtor()
{ {
continue; continue;
} }
auto assignValue = GetFieldInitializerValue(fieldInst); GetFieldInitializerValue(fieldInst, NULL, NULL, NULL, true);
if (assignValue)
{
assignValue = LoadValue(assignValue);
if (!assignValue.mType->IsValuelessType())
{
auto staticVarRef = ReferenceStaticField(fieldInst).mValue;
mBfIRBuilder->CreateStore(assignValue.mValue, staticVarRef);
}
}
} }
} }
} }

View file

@ -1609,7 +1609,7 @@ public:
BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL); BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL);
void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false); void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false);
void ResolveConstField(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field, bool forceResolve = 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); void MarkFieldInitialized(BfFieldInstance* fieldInstance);
bool IsThreadLocal(BfFieldInstance* fieldInstance); bool IsThreadLocal(BfFieldInstance* fieldInstance);
BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field); BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field);

View file

@ -7870,7 +7870,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
BfTypedValue typedVal; BfTypedValue typedVal;
{ {
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true); SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
typedVal = constResolver.Resolve(sizeExpr); typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
} }
if (typedVal.mKind == BfTypedValueKind_GenericConstValue) 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); BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
constResolver.mAllowGenericConstValue = true; constResolver.mAllowGenericConstValue = true;
constResolver.mExpectingType = intType; constResolver.mExpectingType = intType;
BfTypedValue typedVal = constResolver.Resolve(sizeExpr); BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
if (typedVal.mKind == BfTypedValueKind_GenericConstValue) if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
{ {
int elemHash = Hash(typedVal.mType, ctx); 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); BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr);
constResolver.mAllowGenericConstValue = true; constResolver.mAllowGenericConstValue = true;
constResolver.mExpectingType = intType; constResolver.mExpectingType = intType;
BfTypedValue typedVal = constResolver.Resolve(sizeExpr); BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
if (typedVal.mKind == BfTypedValueKind_GenericConstValue) if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
{ {
if (!lhs->IsUnknownSizedArray()) if (!lhs->IsUnknownSizedArray())

View file

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

View file

@ -5,6 +5,7 @@ namespace Tests
class SizedArrays class SizedArrays
{ {
public static int[8] iArr = .(123, 234, 345, ); public static int[8] iArr = .(123, 234, 345, );
public static int[?] iArr2 = .(12, 23, 34);
[Test] [Test]
static void TestBasics() static void TestBasics()
@ -24,6 +25,12 @@ namespace Tests
val2[0][0] = 9; val2[0][0] = 9;
Test.Assert(val0 != val2); Test.Assert(val0 != val2);
Test.Assert(val2[1] == val1); 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] [Test]