1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

ConstEval updates, better const struct support

This commit is contained in:
Brian Fiete 2020-12-22 04:50:37 -08:00
parent 9b80c26d0a
commit be929c3626
21 changed files with 1404 additions and 527 deletions

View file

@ -231,6 +231,9 @@ ContiguousHeap::AllocRef ContiguousHeap::Alloc(int size)
blockList->PushBack(CH_ABS_TO_REL(block)); blockList->PushBack(CH_ABS_TO_REL(block));
mFreeList.Add(CH_ABS_TO_REL(block)); mFreeList.Add(CH_ABS_TO_REL(block));
if (mFreeIdx >= mFreeList.mSize)
mFreeIdx = 0;
} }
} }

View file

@ -790,11 +790,13 @@ void BeIRCodeGen::Read(BeValue*& beValue)
BE_MEM_END("ParamType_Const_AggZero"); BE_MEM_END("ParamType_Const_AggZero");
return; return;
} }
else if (constType == BfConstType_Array) else if (constType == BfConstType_Agg)
{ {
CMD_PARAM(BeType*, type); CMD_PARAM(BeType*, type);
CMD_PARAM(CmdParamVec<BeConstant*>, values); CMD_PARAM(CmdParamVec<BeConstant*>, values);
if (type->IsSizedArray())
{
auto arrayType = (BeSizedArrayType*)type; auto arrayType = (BeSizedArrayType*)type;
int fillCount = (int)(arrayType->mLength - values.size()); int fillCount = (int)(arrayType->mLength - values.size());
if (fillCount > 0) if (fillCount > 0)
@ -803,16 +805,32 @@ void BeIRCodeGen::Read(BeValue*& beValue)
for (int i = 0; i < fillCount; i++) for (int i = 0; i < fillCount; i++)
values.push_back(lastValue); values.push_back(lastValue);
} }
}
else
{
BF_ASSERT(type->IsStruct());
}
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>(); auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>();
constStruct->mType = type; constStruct->mType = type;
for (auto val : values) for (int i = 0; i < (int)values.size(); i++)
{ {
auto val = values[i];
BeConstant* constant = BeValueDynCast<BeConstant>(val); BeConstant* constant = BeValueDynCast<BeConstant>(val);
constStruct->mMemberValues.push_back(constant); constStruct->mMemberValues.push_back(constant);
#ifdef _DEBUG #ifdef _DEBUG
if (type->IsSizedArray())
{
auto arrayType = (BeSizedArrayType*)type;
auto memberType = constant->GetType(); auto memberType = constant->GetType();
BF_ASSERT(memberType == arrayType->mElementType); BF_ASSERT(memberType == arrayType->mElementType);
}
else
{
auto structType = (BeStructType*)type;
auto memberType = constant->GetType();
BF_ASSERT(memberType == structType->mMembers[i].mType);
}
#endif #endif
} }
beValue = constStruct; beValue = constStruct;
@ -1140,14 +1158,16 @@ void BeIRCodeGen::HandleNextCmd()
SetResult(curId, mBeContext->CreateVectorType(elementType, length)); SetResult(curId, mBeContext->CreateVectorType(elementType, length));
} }
break; break;
case BfIRCmd_CreateConstStruct: case BfIRCmd_CreateConstAgg:
{ {
CMD_PARAM(BeType*, type); CMD_PARAM(BeType*, type);
CMD_PARAM(CmdParamVec<BeValue*>, values) CMD_PARAM(CmdParamVec<BeValue*>, values);
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>(); auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>();
constStruct->mType = type; constStruct->mType = type;
BF_ASSERT(type->IsStruct());
if (type->IsStruct())
{
FixValues((BeStructType*)type, values); FixValues((BeStructType*)type, values);
BF_ASSERT(((BeStructType*)type)->mMembers.size() == values.size()); BF_ASSERT(((BeStructType*)type)->mMembers.size() == values.size());
@ -1157,6 +1177,28 @@ void BeIRCodeGen::HandleNextCmd()
BF_ASSERT(mBeContext->AreTypesEqual(((BeStructType*)type)->mMembers[i].mType, val->GetType())); BF_ASSERT(mBeContext->AreTypesEqual(((BeStructType*)type)->mMembers[i].mType, val->GetType()));
constStruct->mMemberValues.push_back(BeValueDynCast<BeConstant>(val)); constStruct->mMemberValues.push_back(BeValueDynCast<BeConstant>(val));
} }
}
else
{
BF_ASSERT(type->IsSizedArray());
auto arrayType = (BeSizedArrayType*)type;
int fillCount = (int)(arrayType->mLength - values.size());
if (fillCount > 0)
{
auto lastValue = values.back();
for (int i = 0; i < fillCount; i++)
values.push_back(lastValue);
}
BF_ASSERT(arrayType->mLength == values.size());
for (int i = 0; i < (int)values.size(); i++)
{
auto val = values[i];
BF_ASSERT(mBeContext->AreTypesEqual(((BeSizedArrayType*)type)->mElementType, val->GetType()));
constStruct->mMemberValues.push_back(BeValueDynCast<BeConstant>(val));
}
}
SetResult(curId, constStruct); SetResult(curId, constStruct);
} }
break; break;
@ -1168,18 +1210,6 @@ void BeIRCodeGen::HandleNextCmd()
SetResult(curId, beConst); SetResult(curId, beConst);
} }
break; break;
case BfIRCmd_CreateConstArray:
{
CMD_PARAM(BeType*, type);
CMD_PARAM(CmdParamVec<BeConstant*>, values);
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>();
constStruct->mType = type;
for (auto val : values)
constStruct->mMemberValues.push_back(BeValueDynCast<BeConstant>(val));
SetResult(curId, constStruct);
}
break;
case BfIRCmd_CreateConstString: case BfIRCmd_CreateConstString:
{ {
CMD_PARAM(String, str); CMD_PARAM(String, str);

View file

@ -2864,6 +2864,39 @@ BeMCOperand BeMCContext::CreateLoad(const BeMCOperand& mcTarget)
return result; return result;
} }
static bool NeedsDecompose(BeConstant* constant)
{
if (auto arrayConst = BeValueDynCast<BeStructConstant>(constant))
{
for (auto& val : arrayConst->mMemberValues)
{
if (NeedsDecompose(val))
return true;
}
return false;
}
if (auto globalVar = BeValueDynCast<BeGlobalVariable>(constant))
{
return true;
}
else if (auto castConst = BeValueDynCast<BeCastConstant>(constant))
{
return true;
}
else if (auto castConst = BeValueDynCast<BeBitCastInst>(constant))
{
if (auto targetConstant = BeValueDynCast<BeConstant>(castConst->mValue))
return NeedsDecompose(targetConstant);
}
else if (auto castConst = BeValueDynCast<BeGEPConstant>(constant))
{
return NeedsDecompose(castConst->mTarget);
}
return false;
}
void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, const BeMCOperand& ptr) void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, const BeMCOperand& ptr)
{ {
BeMCOperand mcVal = val; BeMCOperand mcVal = val;
@ -2871,33 +2904,30 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con
if (mcVal.mKind == BeMCOperandKind_ConstAgg) if (mcVal.mKind == BeMCOperandKind_ConstAgg)
{ {
bool needsDecompose = false; if (auto aggConst = BeValueDynCast<BeStructConstant>(mcVal.mConstant))
if (auto arrayConst = BeValueDynCast<BeStructConstant>(mcVal.mConstant))
{ {
for (auto& val : arrayConst->mMemberValues) if (NeedsDecompose(mcVal.mConstant))
{
if (auto globalVar = BeValueDynCast<BeGlobalVariable>(val))
{
needsDecompose = true;
}
else if (auto castConst = BeValueDynCast<BeCastConstant>(val))
{
needsDecompose = true;
}
}
if (needsDecompose)
{ {
int offset = 0; int offset = 0;
auto arrayType = arrayConst->GetType(); auto aggType = aggConst->GetType();
BEMC_ASSERT(arrayType->IsSizedArray());
auto sizedArrayType = (BeSizedArrayType*)arrayType;
for (auto& val : arrayConst->mMemberValues) for (int memberIdx = 0; memberIdx < (int)aggConst->mMemberValues.size(); memberIdx++)
{ {
auto destOperand = AllocVirtualReg(mModule->mContext->GetPointerTo(sizedArrayType->mElementType)); auto val = aggConst->mMemberValues[memberIdx];
BeType* elemType = NULL;
if (aggType->IsSizedArray())
elemType = ((BeSizedArrayType*)aggType)->mElementType;
else
{
auto& memberInfo = ((BeStructType*)aggType)->mMembers[memberIdx];
offset = memberInfo.mByteOffset;
elemType = memberInfo.mType;
}
if (elemType->mSize == 0)
continue;
auto destOperand = AllocVirtualReg(mModule->mContext->GetPointerTo(elemType));
auto vregInfo = GetVRegInfo(destOperand); auto vregInfo = GetVRegInfo(destOperand);
vregInfo->mDefOnFirstUse = true; vregInfo->mDefOnFirstUse = true;
vregInfo->mRelTo = mcPtr; vregInfo->mRelTo = mcPtr;
@ -2905,12 +2935,13 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con
vregInfo->mRelOffset = BeMCOperand::FromImmediate(offset); vregInfo->mRelOffset = BeMCOperand::FromImmediate(offset);
destOperand.mKind = BeMCOperandKind_VRegLoad; //destOperand.mKind = BeMCOperandKind_VRegLoad;
auto elementVal = GetOperand(val); auto elementVal = GetOperand(val);
AllocInst(instKind, destOperand, elementVal); //AllocInst(instKind, destOperand, elementVal);
CreateStore(instKind, elementVal, destOperand);
offset += sizedArrayType->mElementType->mSize; offset += elemType->mSize;
} }
return; return;
} }
@ -15742,7 +15773,7 @@ void BeMCContext::Generate(BeFunction* function)
mDbgPreferredRegs[32] = X64Reg_R8;*/ mDbgPreferredRegs[32] = X64Reg_R8;*/
//mDbgPreferredRegs[8] = X64Reg_RAX; //mDbgPreferredRegs[8] = X64Reg_RAX;
//mDebugging = (function->mName == "DoCallback"); mDebugging = (function->mName == "?SetDefaults@KeySettings@BeefTest@bf@@QEAAXXZ");
// || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ"); // || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
// ; // ;

View file

@ -3112,8 +3112,6 @@ void BeModule::AddBlock(BeFunction* function, BeBlock* block)
{ {
block->mFunction = function; block->mFunction = function;
function->mBlocks.push_back(block); function->mBlocks.push_back(block);
//block->mFuncRelId = function->mCurElementId++;
} }
void BeModule::RemoveBlock(BeFunction* function, BeBlock* block) void BeModule::RemoveBlock(BeFunction* function, BeBlock* block)

View file

@ -531,7 +531,6 @@ public:
Array<BeFunctionParam> mParams; Array<BeFunctionParam> mParams;
BeDbgFunction* mDbgFunction; BeDbgFunction* mDbgFunction;
BeGlobalVariable* mRemapBindVar; BeGlobalVariable* mRemapBindVar;
int mCurElementId;
public: public:
BeFunction() BeFunction()
@ -549,7 +548,6 @@ public:
mIsDLLExport = false; mIsDLLExport = false;
mIsDLLImport = false; mIsDLLImport = false;
mRemapBindVar = NULL; mRemapBindVar = NULL;
mCurElementId = 0;
} }
BeFunctionType* GetFuncType() BeFunctionType* GetFuncType()

View file

@ -434,6 +434,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mStaticInitAfterAttributeTypeDef = NULL; mStaticInitAfterAttributeTypeDef = NULL;
mStaticInitPriorityAttributeTypeDef = NULL; mStaticInitPriorityAttributeTypeDef = NULL;
mStringTypeDef = NULL; mStringTypeDef = NULL;
mStringViewTypeDef = NULL;
mThreadStaticAttributeTypeDef = NULL; mThreadStaticAttributeTypeDef = NULL;
mTypeTypeDef = NULL; mTypeTypeDef = NULL;
mUnboundAttributeTypeDef = NULL; mUnboundAttributeTypeDef = NULL;
@ -1359,7 +1360,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
StringT<128> typesVariableName; StringT<128> typesVariableName;
BfMangler::MangleStaticFieldName(typesVariableName, GetMangleKind(), typeDefType->ToTypeInstance(), "sTypes", typeDefPtrType); BfMangler::MangleStaticFieldName(typesVariableName, GetMangleKind(), typeDefType->ToTypeInstance(), "sTypes", typeDefPtrType);
auto arrayType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->MapType(typeDefType), (int)typeDataVector.size()); auto arrayType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->MapType(typeDefType), (int)typeDataVector.size());
auto typeDataConst = bfModule->mBfIRBuilder->CreateConstArray(arrayType, typeDataVector); auto typeDataConst = bfModule->mBfIRBuilder->CreateConstAgg_Value(arrayType, typeDataVector);
BfIRValue typeDataArray = bfModule->mBfIRBuilder->CreateGlobalVariable(arrayType, true, BfIRLinkageType_External, BfIRValue typeDataArray = bfModule->mBfIRBuilder->CreateGlobalVariable(arrayType, true, BfIRLinkageType_External,
typeDataConst, typesVariableName); typeDataConst, typesVariableName);
@ -1401,7 +1402,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
{ {
auto elemType = bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_Int8)); auto elemType = bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_Int8));
auto arrayType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->MapType(elemType), (int)forceLinkValues.size()); auto arrayType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->MapType(elemType), (int)forceLinkValues.size());
auto typeDataConst = bfModule->mBfIRBuilder->CreateConstArray(arrayType, forceLinkValues); auto typeDataConst = bfModule->mBfIRBuilder->CreateConstAgg_Value(arrayType, forceLinkValues);
BfIRValue typeDataArray = bfModule->mBfIRBuilder->CreateGlobalVariable(arrayType, true, BfIRLinkageType_Internal, BfIRValue typeDataArray = bfModule->mBfIRBuilder->CreateGlobalVariable(arrayType, true, BfIRLinkageType_Internal,
typeDataConst, "FORCELINK_MODULES"); typeDataConst, "FORCELINK_MODULES");
} }
@ -1431,7 +1432,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
stringList.Add(bfModule->mBfIRBuilder->CreateConstNull(stringPtrIRType)); stringList.Add(bfModule->mBfIRBuilder->CreateConstNull(stringPtrIRType));
BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)stringList.size()); BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)stringList.size());
auto stringArray = bfModule->mBfIRBuilder->CreateConstArray(stringArrayType, stringList); auto stringArray = bfModule->mBfIRBuilder->CreateConstAgg_Value(stringArrayType, stringList);
auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName); auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName);
@ -1459,7 +1460,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
} }
BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)usedStringIdMap.size()); BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)usedStringIdMap.size());
auto stringArray = bfModule->mBfIRBuilder->CreateConstArray(stringArrayType, stringList); auto stringArray = bfModule->mBfIRBuilder->CreateConstAgg_Value(stringArrayType, stringList);
auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName); auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName);
@ -5378,10 +5379,11 @@ void BfCompiler::PopulateReified()
{ {
auto& checkMethodInstanceGroup = typeInst->mMethodInstanceGroups[checkMethodDef->mIdx]; auto& checkMethodInstanceGroup = typeInst->mMethodInstanceGroups[checkMethodDef->mIdx];
auto checkMethodInstance = checkMethodInstanceGroup.mDefault; auto checkMethodInstance = checkMethodInstanceGroup.mDefault;
if (checkMethodInstance == NULL) if (checkMethodInstance != NULL)
continue; {
if ((checkMethodDef->mIsExtern) && (checkMethodInstance->IsReifiedAndImplemented())) if ((checkMethodDef->mIsExtern) && (checkMethodInstance->IsReifiedAndImplemented()))
forceMethod = true; forceMethod = true;
}
checkMethodDef = checkMethodDef->mNextWithSameName; checkMethodDef = checkMethodDef->mNextWithSameName;
} }
} }
@ -6632,6 +6634,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mStaticInitAfterAttributeTypeDef = _GetRequiredType("System.StaticInitAfterAttribute"); mStaticInitAfterAttributeTypeDef = _GetRequiredType("System.StaticInitAfterAttribute");
mStaticInitPriorityAttributeTypeDef = _GetRequiredType("System.StaticInitPriorityAttribute"); mStaticInitPriorityAttributeTypeDef = _GetRequiredType("System.StaticInitPriorityAttribute");
mStringTypeDef = _GetRequiredType("System.String"); mStringTypeDef = _GetRequiredType("System.String");
mStringViewTypeDef = _GetRequiredType("System.StringView");
mTestAttributeTypeDef = _GetRequiredType("System.TestAttribute"); mTestAttributeTypeDef = _GetRequiredType("System.TestAttribute");
mThreadStaticAttributeTypeDef = _GetRequiredType("System.ThreadStaticAttribute"); mThreadStaticAttributeTypeDef = _GetRequiredType("System.ThreadStaticAttribute");
mTypeTypeDef = _GetRequiredType("System.Type"); mTypeTypeDef = _GetRequiredType("System.Type");

View file

@ -349,6 +349,7 @@ public:
BfTypeDef* mActionTypeDef; BfTypeDef* mActionTypeDef;
BfTypeDef* mEnumTypeDef; BfTypeDef* mEnumTypeDef;
BfTypeDef* mStringTypeDef; BfTypeDef* mStringTypeDef;
BfTypeDef* mStringViewTypeDef;
BfTypeDef* mTypeTypeDef; BfTypeDef* mTypeTypeDef;
BfTypeDef* mValueTypeTypeDef; BfTypeDef* mValueTypeTypeDef;
BfTypeDef* mResultTypeDef; BfTypeDef* mResultTypeDef;

View file

@ -59,14 +59,26 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
if (initializer != NULL) if (initializer != NULL)
{ {
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(initializer)) if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(initializer))
{
if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(invocationExpr->mTarget))
{
// Dot-initialized
if (memberRefExpr->mTarget == NULL)
arraySize = (int)invocationExpr->mArguments.size(); arraySize = (int)invocationExpr->mArguments.size();
} }
}
}
if (arraySize != -1) if (arraySize != -1)
{ {
mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
return mResult; return mResult;
} }
else
{
mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
return mResult;
}
} }
} }
@ -411,7 +423,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
if (expandedParamsElementType != NULL) if (expandedParamsElementType != NULL)
{ {
auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size()); auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
auto constArray = mModule->mBfIRBuilder->CreateConstArray(arrayType, expandedParamsConstValues); auto constArray = mModule->mBfIRBuilder->CreateConstAgg(arrayType, expandedParamsConstValues);
llvmArgs.push_back(constArray); llvmArgs.push_back(constArray);
} }

View file

@ -2628,6 +2628,25 @@ BfAutoComplete* BfExprEvaluator::GetAutoComplete()
return mModule->mCompiler->mResolvePassData->mAutoComplete; return mModule->mCompiler->mResolvePassData->mAutoComplete;
} }
bool BfExprEvaluator::IsConstEval()
{
return (mModule->mIsConstModule) || ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0);
}
bool BfExprEvaluator::IsConstEvalEntry()
{
if (mModule->mIsConstModule)
return false;
return ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0);
}
int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic)
{
if (IsConstEval())
return -1;
return methodInstance->GetStructRetIdx(forceStatic);
}
BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType)
{ {
if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodInstance == NULL) || (bindType == NULL)) if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodInstance == NULL) || (bindType == NULL))
@ -3165,7 +3184,7 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant)
if (sizedArray->mElementCount > charValues.size()) if (sizedArray->mElementCount > charValues.size())
charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, 0)); charValues.Add(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Char8, 0));
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstArray(mModule->mBfIRBuilder->MapType(sizedArray), charValues), sizedArray); mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(sizedArray), charValues), sizedArray);
return; return;
} }
} }
@ -4913,7 +4932,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
} }
else else
{ {
auto val = mModule->GetDefaultTypedValue(returnType, true, (methodInstance->GetStructRetIdx() != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value); auto val = mModule->GetDefaultTypedValue(returnType, true, (GetStructRetIdx(methodInstance) != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
if (val.mKind == BfTypedValueKind_Addr) if (val.mKind == BfTypedValueKind_Addr)
val.mKind = BfTypedValueKind_RestrictedTempAddr; val.mKind = BfTypedValueKind_RestrictedTempAddr;
return val; return val;
@ -4921,7 +4940,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
}; };
mModule->PopulateType(origReturnType, BfPopulateType_Data); mModule->PopulateType(origReturnType, BfPopulateType_Data);
if (methodInstance->GetStructRetIdx() != -1) if (GetStructRetIdx(methodInstance) != -1)
{ {
// We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied // We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied
// This happens for returning Result<T>'s with a 'T' value // This happens for returning Result<T>'s with a 'T' value
@ -4982,6 +5001,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
return result; return result;
} }
bool forceBind = false;
if (mModule->mCompiler->mCEMachine != NULL) if (mModule->mCompiler->mCEMachine != NULL)
{ {
if (mModule->mIsConstModule) if (mModule->mIsConstModule)
@ -4990,18 +5011,33 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
} }
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0) else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
{ {
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, CeEvalFlags_None); if (mFunctionBindResult != NULL)
{
forceBind = true;
}
else if (mUsedAsStatement)
{
// Don't allow use in a cascade
}
else
{
CeEvalFlags evalFlags = CeEvalFlags_None;
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
if (constRet) if (constRet)
return constRet; return constRet;
} }
} }
}
if (!forceBind)
{
if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites)) if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites))
{ {
// We don't actually submit method calls for unspecialized methods // We don't actually submit method calls for unspecialized methods
// - this includes all methods in unspecialized types // - this includes all methods in unspecialized types
return _GetDefaultReturnValue(); return _GetDefaultReturnValue();
} }
}
if (methodInstance->mVirtualTableIdx != -1) if (methodInstance->mVirtualTableIdx != -1)
{ {
@ -5142,7 +5178,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
if (irArgs.size() != 0) if (irArgs.size() != 0)
{ {
auto targetType = methodInstance->mMethodInstanceGroup->mOwner; auto targetType = methodInstance->mMethodInstanceGroup->mOwner;
if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat())) if ((targetType->IsValueType()) && (targetType->IsSplattable()) && (!methodDef->HasNoThisSplat()) && (!IsConstEval()))
mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead); mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, BfTypedValueKind_SplatHead);
else else
mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value); mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value);
@ -5214,7 +5250,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
if (sret != NULL) if (sret != NULL)
{ {
SizedArray<BfIRValue, 8> sretIRArgs; SizedArray<BfIRValue, 8> sretIRArgs;
int sretIdx = methodInstance->GetStructRetIdx(); int sretIdx = GetStructRetIdx(methodInstance);
int inIdx = 0; int inIdx = 0;
for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++) for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++)
{ {
@ -5256,7 +5292,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
if (methodInstance->mIsIntrinsic) if (methodInstance->mIsIntrinsic)
break; break;
if (argIdx == methodInstance->GetStructRetIdx()) if (argIdx == GetStructRetIdx(methodInstance))
{ {
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet); mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
argIdx++; argIdx++;
@ -5303,7 +5339,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
mModule->PopulateType(paramType, BfPopulateType_Data); mModule->PopulateType(paramType, BfPopulateType_Data);
auto typeInst = paramType->ToTypeInstance(); auto typeInst = paramType->ToTypeInstance();
if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable())) if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsConstEval()))
{ {
// We're splatting // We're splatting
} }
@ -5346,7 +5382,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
doingThis = false; doingThis = false;
continue; continue;
} }
bool isSplatted = methodInstance->GetParamIsSplat(thisIdx); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating); bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsConstEval()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating);
if (isSplatted) if (isSplatted)
{ {
BfTypeUtils::SplatIterate(_HandleParamType, paramType); BfTypeUtils::SplatIterate(_HandleParamType, paramType);
@ -5380,7 +5416,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
continue; continue;
} }
if (methodInstance->GetParamIsSplat(paramIdx)) if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsConstEval()))
{ {
BfTypeUtils::SplatIterate(_HandleParamType, paramType); BfTypeUtils::SplatIterate(_HandleParamType, paramType);
paramIdx++; paramIdx++;
@ -5575,6 +5611,7 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& i
else if (!checkType->IsValuelessType()) else if (!checkType->IsValuelessType())
{ {
auto loadedVal = mModule->LoadValue(curValue); auto loadedVal = mModule->LoadValue(curValue);
loadedVal = mModule->PrepareConst(loadedVal);
irArgs.push_back(loadedVal.mValue); irArgs.push_back(loadedVal.mValue);
} }
}; };
@ -5595,7 +5632,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
return; return;
bool wantSplat = false; bool wantSplat = false;
if ((argVal.mType->IsSplattable()) && (!disableSplat)) if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsConstEval()))
{ {
disableLowering = true; disableLowering = true;
auto argTypeInstance = argVal.mType->ToTypeInstance(); auto argTypeInstance = argVal.mType->ToTypeInstance();
@ -5611,14 +5648,18 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
{ {
if (argVal.mType->IsComposite()) if (argVal.mType->IsComposite())
{ {
if (isIntrinsic) if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
{
// Const eval entry - we want any incoming consts as they are
}
else if (isIntrinsic)
{ {
// We can handle composites either by value or not // We can handle composites either by value or not
} }
else else
argVal = mModule->MakeAddressable(argVal); argVal = mModule->MakeAddressable(argVal);
if ((!disableLowering) && (!isIntrinsic)) if ((!IsConstEval()) && (!disableLowering) && (!isIntrinsic))
{ {
BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None;
@ -5709,7 +5750,15 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth
if (argVal.mType->IsValuelessType()) if (argVal.mType->IsValuelessType())
return; return;
if ((!methodInstance->AllowsThisSplatting()) || (methodDef->mIsMutating)) auto owner = methodInstance->GetOwner();
bool allowThisSplatting;
if (mModule->mIsConstModule)
allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessType();
else
allowThisSplatting = methodInstance->AllowsThisSplatting();
if ((!allowThisSplatting) || (methodDef->mIsMutating))
{ {
argVal = mModule->MakeAddressable(argVal); argVal = mModule->MakeAddressable(argVal);
irArgs.push_back(argVal.mValue); irArgs.push_back(argVal.mValue);
@ -6007,7 +6056,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
} }
else else
{ {
wantsSplat = methodInstance->GetParamIsSplat(paramIdx); wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsConstEval());
if (methodInstance->IsImplicitCapture(paramIdx)) if (methodInstance->IsImplicitCapture(paramIdx))
{ {
auto paramType = methodInstance->GetParamType(paramIdx); auto paramType = methodInstance->GetParamType(paramIdx);
@ -6474,7 +6523,7 @@ SplatArgs(lookupVal, irArgs);
else else
{ {
// We need to make a temp and get the addr of that // We need to make a temp and get the addr of that
if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr())) if ((!wantsSplat) && (!argValue.IsValuelessType()) && (!argValue.IsAddr()) && (!IsConstEvalEntry()))
{ {
argValue = mModule->MakeAddressable(argValue); argValue = mModule->MakeAddressable(argValue);
} }
@ -10828,7 +10877,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
hasThis = true; hasThis = true;
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes); methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
int thisIdx = 0; int thisIdx = 0;
if (methodInstance->GetStructRetIdx() == 0) if (GetStructRetIdx(methodInstance) == 0)
thisIdx = 1; thisIdx = 1;
irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance); irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance);
} }
@ -10846,10 +10895,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes); auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName); funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
if (methodInstance->GetStructRetIdx() != -1) if (GetStructRetIdx(methodInstance) != -1)
{ {
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_NoAlias); mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_NoAlias);
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_StructRet);
} }
auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance); auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
@ -10867,9 +10916,9 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
SizedArray<BfIRValue, 8> irArgs; SizedArray<BfIRValue, 8> irArgs;
int argIdx = 0; int argIdx = 0;
if (bindMethodInstance->GetStructRetIdx() == 0) if (GetStructRetIdx(bindMethodInstance) == 0)
{ {
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx())); irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance)));
argIdx++; argIdx++;
} }
@ -10889,7 +10938,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
} }
int thisIdx = 0; int thisIdx = 0;
if (methodInstance->GetStructRetIdx() == 0) if (GetStructRetIdx(methodInstance) == 0)
thisIdx = 1; thisIdx = 1;
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx); auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx);
BfTypedValue typedVal(fieldPtr, fieldType, true); BfTypedValue typedVal(fieldPtr, fieldType, true);
@ -10900,16 +10949,16 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (hasThis) if (hasThis)
argIdx++; argIdx++;
if (bindMethodInstance->GetStructRetIdx() == 1) if (GetStructRetIdx(bindMethodInstance) == 1)
{ {
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx())); irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance)));
argIdx++; argIdx++;
} }
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
{ {
auto paramType = methodInstance->GetParamType(paramIdx); auto paramType = methodInstance->GetParamType(paramIdx);
if (paramType->IsSplattable()) if ((paramType->IsSplattable()) && (!IsConstEval()))
{ {
BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType); BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++)); }, paramType);
} }
@ -10923,12 +10972,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (mModule->mCompiler->mOptions.mAllowHotSwapping) if (mModule->mCompiler->mOptions.mAllowHotSwapping)
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal); bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs); auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
if (bindMethodInstance->GetStructRetIdx() != -1) if (GetStructRetIdx(bindMethodInstance) != -1)
mModule->mBfIRBuilder->Call_AddAttribute(callInst, bindMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); mModule->mBfIRBuilder->Call_AddAttribute(callInst, GetStructRetIdx(bindMethodInstance) + 1, BfIRAttribute_StructRet);
auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance); auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
if (destCallingConv != BfIRCallingConv_CDecl) if (destCallingConv != BfIRCallingConv_CDecl)
mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv); mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv);
if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->GetStructRetIdx() != -1)) if ((methodInstance->mReturnType->IsValuelessType()) || (GetStructRetIdx(methodInstance) != -1))
{ {
mModule->mBfIRBuilder->CreateRetVoid(); mModule->mBfIRBuilder->CreateRetVoid();
} }
@ -11777,15 +11826,15 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
SizedArray<BfIRType, 3> newTypes; SizedArray<BfIRType, 3> newTypes;
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx(forceStatic) == 0)) if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 0))
newTypes.push_back(origParamTypes[0]); newTypes.push_back(origParamTypes[0]);
if (!methodDef->mIsStatic) if (!methodDef->mIsStatic)
newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance)); newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx(forceStatic) == 1)) if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 1))
newTypes.push_back(origParamTypes[1]); newTypes.push_back(origParamTypes[1]);
int paramStartIdx = 0; int paramStartIdx = 0;
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx(forceStatic) != -1)) if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) != -1))
paramStartIdx++; paramStartIdx++;
if (!methodDef->mIsStatic) if (!methodDef->mIsStatic)
paramStartIdx++; paramStartIdx++;
@ -13143,11 +13192,17 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
else else
{ {
if (isAppendAlloc) if (isAppendAlloc)
{
allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign); allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign);
}
else else
{ {
allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign); allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
} }
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0) && (mModule->mCompiler->mCEMachine != NULL))
{
mModule->mCompiler->mCEMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
}
mResult = BfTypedValue(allocValue, resultType); mResult = BfTypedValue(allocValue, resultType);
} }
@ -13195,7 +13250,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
{ {
mModule->AssertErrorState(); mModule->AssertErrorState();
} }
else else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) == 0)
{ {
SizedArray<BfIRValue, 1> irArgs; SizedArray<BfIRValue, 1> irArgs;
irArgs.push_back(mResult.mValue); irArgs.push_back(mResult.mValue);
@ -13203,7 +13258,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
} }
} }
if ((isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck)) if ((!mModule->mIsConstModule) && (isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck))
{ {
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers"); BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
BF_ASSERT(markMethod != NULL); BF_ASSERT(markMethod != NULL);
@ -13267,9 +13322,16 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
} }
if (!typeInstance->IsValuelessType()) if (!typeInstance->IsValuelessType())
bindResult.mIRArgs.Insert(0, mResult.mValue); bindResult.mIRArgs.Insert(0, mResult.mValue);
CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs); auto result = CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
if ((result) && (!result.mType->IsVoid()))
mResult = result;
} }
} }
if (((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0) && (mModule->mCompiler->mCEMachine != NULL))
{
mModule->mCompiler->mCEMachine->ClearAppendAllocInfo();
}
} }
void BfExprEvaluator::Visit(BfBoxExpression* boxExpr) void BfExprEvaluator::Visit(BfBoxExpression* boxExpr)
@ -13460,6 +13522,8 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
if ((target.mType->IsStruct()) && (!target.IsAddr())) if ((target.mType->IsStruct()) && (!target.IsAddr()))
{ {
if (IsConstEvalEntry())
return target;
target = mModule->MakeAddressable(target); target = mModule->MakeAddressable(target);
} }
@ -13494,7 +13558,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
auto ptrType = mModule->CreatePointerType(primStructType); auto ptrType = mModule->CreatePointerType(primStructType);
target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true); target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
} }
else if ((primStructType->IsSplattable()) && (target.IsSplat())) else if ((primStructType->IsSplattable()) && (target.IsSplat()) && (!IsConstEval()))
{ {
target.mType = primStructType; target.mType = primStructType;
target.mKind = BfTypedValueKind_SplatHead; target.mKind = BfTypedValueKind_SplatHead;
@ -14865,7 +14929,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
else else
mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr); mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr);
MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, false); auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, false);
if ((ctorResult) && (!ctorResult.mType->IsVoid()))
mResult = ctorResult;
mModule->ValidateAllocation(expectingType, invocationExpr->mTarget); mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
return; return;
@ -15364,6 +15430,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
} }
} }
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0))
mModule->Fail("Cascade operator cannot be used in const evaluation", cascadeOperatorToken);
SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade); SetAndRestoreValue<bool> prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade);
ResolveArgValues(argValues, resolveArgsFlags); ResolveArgValues(argValues, resolveArgsFlags);
mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind); mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind);
@ -15875,7 +15944,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
} }
else else
{ {
auto val = mModule->GetDefaultTypedValue(returnType, true, (methodInstance.mMethodInstance->GetStructRetIdx() != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value); auto val = mModule->GetDefaultTypedValue(returnType, true, (GetStructRetIdx(methodInstance.mMethodInstance) != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
if (val.mKind == BfTypedValueKind_Addr) if (val.mKind == BfTypedValueKind_Addr)
val.mKind = BfTypedValueKind_TempAddr; val.mKind = BfTypedValueKind_TempAddr;
return val; return val;
@ -17390,7 +17459,7 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
return mModule->mBfIRBuilder->CreateConstStructZero(mModule->mBfIRBuilder->MapType(checkArrayType)); return mModule->mBfIRBuilder->CreateConstStructZero(mModule->mBfIRBuilder->MapType(checkArrayType));
} }
else else
return mModule->mBfIRBuilder->CreateConstArray(mModule->mBfIRBuilder->MapType(checkArrayType), members); return mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(checkArrayType), members);
}; };
_GetValues(arrayType, openToken, valueExprs, commas, closeToken, false); _GetValues(arrayType, openToken, valueExprs, commas, closeToken, false);

View file

@ -383,6 +383,9 @@ public:
void FinishExpressionResult(); void FinishExpressionResult();
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode); virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode);
BfAutoComplete* GetAutoComplete(); BfAutoComplete* GetAutoComplete();
bool IsConstEval();
bool IsConstEvalEntry();
int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false);
BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken); BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken);
void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true); void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true);
BfType* BindGenericType(BfAstNode* node, BfType* bindType); BfType* BindGenericType(BfAstNode* node, BfType* bindType);

View file

@ -406,12 +406,12 @@ int BfIRConstHolder::IsZero(BfIRValue value)
if (constant->mConstType == BfConstType_AggZero) if (constant->mConstType == BfConstType_AggZero)
return 1; return 1;
if (constant->mConstType == BfConstType_Array) if (constant->mConstType == BfConstType_Agg)
{ {
auto constArr = (BfConstantArray*)constant; auto constAgg = (BfConstantAgg*)constant;
for (int i = 0; i < constArr->mValues.mSize; i++) for (int i = 0; i < constAgg->mValues.mSize; i++)
{ {
int elemResult = IsZero(constArr->mValues[i]); int elemResult = IsZero(constAgg->mValues[i]);
if (elemResult != 1) if (elemResult != 1)
return elemResult; return elemResult;
} }
@ -454,17 +454,17 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs)
return (constLHS->mUInt64 == constRHS->mUInt64) ? 1 : 0; return (constLHS->mUInt64 == constRHS->mUInt64) ? 1 : 0;
} }
if (constLHS->mConstType == BfConstType_Array) if (constLHS->mConstType == BfConstType_Agg)
{ {
auto arrayLHS = (BfConstantArray*)constLHS; auto aggLHS = (BfConstantAgg*)constLHS;
auto arrayRHS = (BfConstantArray*)constRHS; auto aggRHS = (BfConstantAgg*)constRHS;
if (arrayLHS->mValues.mSize != arrayRHS->mValues.mSize) if (aggLHS->mValues.mSize != aggRHS->mValues.mSize)
return -1; return -1;
for (int i = 0; i < arrayLHS->mValues.mSize; i++) for (int i = 0; i < aggLHS->mValues.mSize; i++)
{ {
int elemResult = CheckConstEquality(arrayLHS->mValues[i], arrayRHS->mValues[i]); int elemResult = CheckConstEquality(aggLHS->mValues[i], aggRHS->mValues[i]);
if (elemResult != 1) if (elemResult != 1)
return elemResult; return elemResult;
} }
@ -641,18 +641,18 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
auto aggZero = (BfConstant*)fromConst; auto aggZero = (BfConstant*)fromConst;
return CreateConstStructZero(fromConst->mIRType); return CreateConstStructZero(fromConst->mIRType);
} }
else if (fromConst->mConstType == BfConstType_Array) else if (fromConst->mConstType == BfConstType_Agg)
{ {
auto constArray = (BfConstantArray*)fromConst; auto constAgg = (BfConstantAgg*)fromConst;
BfSizedVector<BfIRValue, 8> copiedVals; BfSizedVector<BfIRValue, 8> copiedVals;
copiedVals.reserve(constArray->mValues.size()); copiedVals.reserve(constAgg->mValues.size());
for (auto fromVal : constArray->mValues) for (auto fromVal : constAgg->mValues)
{ {
auto elementConst = fromHolder->GetConstant(fromVal); auto elementConst = fromHolder->GetConstant(fromVal);
copiedVals.push_back(CreateConst(elementConst, fromHolder)); copiedVals.push_back(CreateConst(elementConst, fromHolder));
} }
return CreateConstArray(constArray->mType, copiedVals); return CreateConstAgg(constAgg->mType, copiedVals);
} }
else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId)) else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId))
{ {
@ -722,10 +722,10 @@ BfIRValue BfIRConstHolder::CreateConstStructZero(BfIRType aggType)
return irValue; return irValue;
} }
BfIRValue BfIRConstHolder::CreateConstArray(BfIRType type, const BfSizedArray<BfIRValue>& values) BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values)
{ {
BfConstantArray* constant = mTempAlloc.Alloc<BfConstantArray>(); BfConstantAgg* constant = mTempAlloc.Alloc<BfConstantAgg>();
constant->mConstType = BfConstType_Array; constant->mConstType = BfConstType_Agg;
constant->mType = type = type; constant->mType = type = type;
auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
@ -1286,17 +1286,17 @@ String BfIRBuilder::ToString(BfIRValue irValue)
BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget);
return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType); return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType);
} }
else if (constant->mConstType == BfConstType_Array) else if (constant->mConstType == BfConstType_Agg)
{ {
auto constArray = (BfConstantArray*)constant; auto constAgg = (BfConstantAgg*)constant;
String str = ToString(constArray->mType); String str = ToString(constAgg->mType);
str += "("; str += "(";
for (int i = 0; i < (int)constArray->mValues.size(); i++) for (int i = 0; i < (int)constAgg->mValues.size(); i++)
{ {
if (i > 0) if (i > 0)
str += ", "; str += ", ";
str += ToString(constArray->mValues[i]); str += ToString(constAgg->mValues[i]);
} }
str += ");"; str += ");";
return str; return str;
@ -1915,9 +1915,9 @@ void BfIRBuilder::Write(const BfIRValue& irValue)
Write(constant->mIRType); Write(constant->mIRType);
} }
break; break;
case (int)BfConstType_Array: case (int)BfConstType_Agg:
{ {
auto arrayConst = (BfConstantArray*)constant; auto arrayConst = (BfConstantAgg*)constant;
Write(arrayConst->mType); Write(arrayConst->mType);
Write(arrayConst->mValues); Write(arrayConst->mValues);
} }
@ -2316,9 +2316,9 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
if (arrayType->mElementType->IsValuelessType()) if (arrayType->mElementType->IsValuelessType())
irType = elementIrType; irType = elementIrType;
else if (arrayType->mElementType->IsSizeAligned()) else if (arrayType->mElementType->IsSizeAligned())
irType = GetSizedArrayType(MapType(arrayType->mElementType), arrayType->mElementCount); irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0));
else else
irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), arrayType->mSize); irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), BF_MAX(arrayType->mSize, 0));
if (wantDIData) if (wantDIData)
diType = DbgCreateArrayType((int64)arrayType->mSize * 8, arrayType->mAlign * 8, DbgGetType(arrayType->mElementType), arrayType->mElementCount); diType = DbgCreateArrayType((int64)arrayType->mSize * 8, arrayType->mAlign * 8, DbgGetType(arrayType->mElementType), arrayType->mElementCount);
@ -2710,7 +2710,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
if (isOptimized) if (isOptimized)
continue; continue;
if ((constant->mConstType == BfConstType_Array) || if ((constant->mConstType == BfConstType_Agg) ||
(constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_AggZero) ||
(constant->mTypeCode == BfTypeCode_NullPtr)) (constant->mTypeCode == BfTypeCode_NullPtr))
{ {
@ -3555,6 +3555,7 @@ BfIRType BfIRBuilder::GetPointerTo(BfIRType type)
BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length) BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length)
{ {
BF_ASSERT(length >= 0);
if (mIgnoreWrites) if (mIgnoreWrites)
{ {
auto constSizedArrayType = mTempAlloc.Alloc<BfConstantSizedArrayType>(); auto constSizedArrayType = mTempAlloc.Alloc<BfConstantSizedArrayType>();
@ -3584,27 +3585,13 @@ BfIRType BfIRBuilder::GetVectorType(BfIRType elementType, int length)
return retType; return retType;
} }
BfIRValue BfIRBuilder::CreateConstStruct(BfIRType type, const BfSizedArray<BfIRValue>& values) BfIRValue BfIRBuilder::CreateConstAgg_Value(BfIRType type, const BfSizedArray<BfIRValue>& values)
{ {
BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstStruct, type, values); BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstAgg, type, values);
NEW_CMD_INSERTED_IRVALUE; NEW_CMD_INSERTED_IRVALUE;
return retVal; return retVal;
} }
/*BfIRValue BfIRBuilder::CreateConstStructZero(BfIRType type)
{
BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstStructZero, type);
NEW_CMD_INSERTED_IRVALUE;
return retVal;
}
BfIRValue BfIRBuilder::CreateConstArray(BfIRType type, const BfSizedArray<BfIRValue>& values)
{
BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstArray, type, values);
NEW_CMD_INSERTED_IRVALUE;
return retVal;
}*/
BfIRValue BfIRBuilder::CreateConstString(const StringImpl& str) BfIRValue BfIRBuilder::CreateConstString(const StringImpl& str)
{ {
BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstString, str); BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstString, str);
@ -3620,8 +3607,8 @@ BfIRValue BfIRBuilder::ConstToMemory(BfIRValue constVal)
return *value; return *value;
BfIRType constType; BfIRType constType;
if (constant->mConstType == BfConstType_Array) if (constant->mConstType == BfConstType_Agg)
constType = ((BfConstantArray*)constant)->mType; constType = ((BfConstantAgg*)constant)->mType;
else if (constant->mConstType == BfConstType_AggZero) else if (constant->mConstType == BfConstType_AggZero)
constType = constant->mIRType; constType = constant->mIRType;
else if (constant->mTypeCode == BfTypeCode_NullPtr) else if (constant->mTypeCode == BfTypeCode_NullPtr)
@ -4181,9 +4168,9 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx)
auto aggConstant = GetConstant(val); auto aggConstant = GetConstant(val);
if (aggConstant != NULL) if (aggConstant != NULL)
{ {
if (aggConstant->mConstType == BfConstType_Array) if (aggConstant->mConstType == BfConstType_Agg)
{ {
auto arrayConstant = (BfConstantArray*)aggConstant; auto arrayConstant = (BfConstantAgg*)aggConstant;
return arrayConstant->mValues[idx]; return arrayConstant->mValues[idx];
} }
@ -4223,7 +4210,7 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, BfIRValue idx)
auto arrConst = GetConstant(val); auto arrConst = GetConstant(val);
if (arrConst != NULL) if (arrConst != NULL)
{ {
if ((arrConst->mConstType == BfConstType_Array) || (arrConst->mConstType == BfConstType_AggZero)) if ((arrConst->mConstType == BfConstType_Agg) || (arrConst->mConstType == BfConstType_AggZero))
{ {
BfIRValue arrMemVal = ConstToMemory(val); BfIRValue arrMemVal = ConstToMemory(val);
auto valAddr = CreateInBoundsGEP(arrMemVal, CreateConst(BfTypeCode_IntPtr, 0), idx); auto valAddr = CreateInBoundsGEP(arrMemVal, CreateConst(BfTypeCode_IntPtr, 0), idx);
@ -4670,6 +4657,11 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT
NEW_CMD_INSERTED_IRVALUE; NEW_CMD_INSERTED_IRVALUE;
mFunctionMap[name] = retVal; mFunctionMap[name] = retVal;
if ((mModule->mIsConstModule) && (name.Contains("Dbg_")))
{
NOP;
}
//BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule); //BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule);
return retVal; return retVal;
@ -4955,7 +4947,6 @@ void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm)
NEW_CMD_INSERTED_IRBLOCK; NEW_CMD_INSERTED_IRBLOCK;
if (!mIgnoreWrites) if (!mIgnoreWrites)
{ {
BF_ASSERT(!value.IsConst());
BF_ASSERT(!retBlock.IsFake()); BF_ASSERT(!retBlock.IsFake());
mActualInsertBlock = retBlock; mActualInsertBlock = retBlock;
} }

View file

@ -121,7 +121,7 @@ enum BfConstType
BfConstType_IntToPtr, BfConstType_IntToPtr,
BfConstType_TypeOf, BfConstType_TypeOf,
BfConstType_AggZero, BfConstType_AggZero,
BfConstType_Array, BfConstType_Agg,
BfConstType_ArrayZero, BfConstType_ArrayZero,
BfConstType_ArrayZero8, BfConstType_ArrayZero8,
BfConstType_Undef, BfConstType_Undef,
@ -161,9 +161,8 @@ enum BfIRCmd : uint8
BfIRCmd_GetSizedArrayType, BfIRCmd_GetSizedArrayType,
BfIRCmd_GetVectorType, BfIRCmd_GetVectorType,
BfIRCmd_CreateConstStruct,
BfIRCmd_CreateConstStructZero, BfIRCmd_CreateConstStructZero,
BfIRCmd_CreateConstArray, BfIRCmd_CreateConstAgg,
BfIRCmd_CreateConstArrayZero, BfIRCmd_CreateConstArrayZero,
BfIRCmd_CreateConstString, BfIRCmd_CreateConstString,
BfIRCmd_ConfigConst, BfIRCmd_ConfigConst,
@ -855,7 +854,7 @@ struct BfConstantExtractValue
int mIdx0; int mIdx0;
}; };
struct BfConstantArray struct BfConstantAgg
{ {
BfConstType mConstType; BfConstType mConstType;
BfIRType mType; BfIRType mType;
@ -900,7 +899,7 @@ public:
BfIRValue CreateConstNull(); BfIRValue CreateConstNull();
BfIRValue CreateConstNull(BfIRType nullType); BfIRValue CreateConstNull(BfIRType nullType);
BfIRValue CreateConstStructZero(BfIRType aggType); BfIRValue CreateConstStructZero(BfIRType aggType);
BfIRValue CreateConstArray(BfIRType type, const BfSizedArray<BfIRValue>& values); BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values);
BfIRValue CreateConstArrayZero(BfIRType type, int count); BfIRValue CreateConstArrayZero(BfIRType type, int count);
BfIRValue CreateConstArrayZero(int count); BfIRValue CreateConstArrayZero(int count);
BfIRValue CreateTypeOf(BfType* type); BfIRValue CreateTypeOf(BfType* type);
@ -1116,7 +1115,7 @@ public:
BfIRType GetSizedArrayType(BfIRType elementType, int length); BfIRType GetSizedArrayType(BfIRType elementType, int length);
BfIRType GetVectorType(BfIRType elementType, int length); BfIRType GetVectorType(BfIRType elementType, int length);
BfIRValue CreateConstStruct(BfIRType type, const BfSizedArray<BfIRValue>& values); BfIRValue CreateConstAgg_Value(BfIRType type, const BfSizedArray<BfIRValue>& values);
BfIRValue CreateConstString(const StringImpl& string); BfIRValue CreateConstString(const StringImpl& string);
BfIRValue ConstToMemory(BfIRValue constVal); BfIRValue ConstToMemory(BfIRValue constVal);
BfIRValue GetConfigConst(BfIRConfigConst constType, BfTypeCode typeCode); BfIRValue GetConfigConst(BfIRConfigConst constType, BfTypeCode typeCode);

View file

@ -882,18 +882,26 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
llvmValue = llvm::ConstantExpr::getPtrToInt(target, llvmToType); llvmValue = llvm::ConstantExpr::getPtrToInt(target, llvmToType);
return; return;
} }
else if (constType == BfConstType_IntToPtr)
{
CMD_PARAM(llvm::Constant*, target);
CMD_PARAM(llvm::Type*, toType);
llvmValue = llvm::ConstantExpr::getIntToPtr(target, toType);
return;
}
else if (constType == BfConstType_AggZero) else if (constType == BfConstType_AggZero)
{ {
CMD_PARAM(llvm::Type*, type); CMD_PARAM(llvm::Type*, type);
llvmValue = llvm::ConstantAggregateZero::get(type); llvmValue = llvm::ConstantAggregateZero::get(type);
return; return;
} }
else if (constType == BfConstType_Array) else if (constType == BfConstType_Agg)
{ {
CMD_PARAM(llvm::Type*, type); CMD_PARAM(llvm::Type*, type);
CMD_PARAM(CmdParamVec<llvm::Constant*>, values); CMD_PARAM(CmdParamVec<llvm::Constant*>, values);
auto arrayType = (llvm::ArrayType*)type; if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(type))
{
int fillCount = (int)(arrayType->getNumElements() - values.size()); int fillCount = (int)(arrayType->getNumElements() - values.size());
if (fillCount > 0) if (fillCount > 0)
{ {
@ -901,8 +909,17 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
for (int i = 0; i < fillCount; i++) for (int i = 0; i < fillCount; i++)
values.push_back(lastValue); values.push_back(lastValue);
} }
llvmValue = llvm::ConstantArray::get(arrayType, values);
}
else if (auto structType = llvm::dyn_cast<llvm::StructType>(type))
{
llvmValue = llvm::ConstantStruct::get(structType, values);
}
else
{
Fail("Bad type");
}
llvmValue = llvm::ConstantArray::get((llvm::ArrayType*)type, values);
return; return;
} }
@ -1616,19 +1633,43 @@ void BfIRCodeGen::HandleNextCmd()
SetResult(curId, llvm::FixedVectorType::get(elementType, length)); SetResult(curId, llvm::FixedVectorType::get(elementType, length));
} }
break; break;
case BfIRCmd_CreateConstStruct: case BfIRCmd_CreateConstAgg:
{ {
CMD_PARAM(llvm::Type*, type); CMD_PARAM(llvm::Type*, type);
CMD_PARAM(CmdParamVec<llvm::Value*>, values) CMD_PARAM(CmdParamVec<llvm::Value*>, values)
llvm::SmallVector<llvm::Constant*, 8> copyValues; llvm::SmallVector<llvm::Constant*, 8> copyValues;
FixValues((llvm::StructType*)type, values);
if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(type))
{
for (auto val : values) for (auto val : values)
{ {
auto constValue = llvm::dyn_cast<llvm::Constant>(val); auto constValue = llvm::dyn_cast<llvm::Constant>(val);
BF_ASSERT(constValue != NULL); BF_ASSERT(constValue != NULL);
copyValues.push_back(constValue); copyValues.push_back(constValue);
} }
SetResult(curId, llvm::ConstantStruct::get((llvm::StructType*)type, copyValues));
int fillCount = (int)(arrayType->getNumElements() - copyValues.size());
if (fillCount > 0)
{
auto lastValue = copyValues.back();
for (int i = 0; i < fillCount; i++)
copyValues.push_back(lastValue);
}
SetResult(curId, llvm::ConstantArray::get(arrayType, copyValues));
}
else if (auto structType = llvm::dyn_cast<llvm::StructType>(type))
{
FixValues(structType, values);
for (auto val : values)
{
auto constValue = llvm::dyn_cast<llvm::Constant>(val);
BF_ASSERT(constValue != NULL);
copyValues.push_back(constValue);
}
SetResult(curId, llvm::ConstantStruct::get(structType, copyValues));
}
else
Fail("Bad type");
} }
break; break;
case BfIRCmd_CreateConstStructZero: case BfIRCmd_CreateConstStructZero:
@ -1637,13 +1678,6 @@ void BfIRCodeGen::HandleNextCmd()
SetResult(curId, llvm::ConstantAggregateZero::get(type)); SetResult(curId, llvm::ConstantAggregateZero::get(type));
} }
break; break;
case BfIRCmd_CreateConstArray:
{
CMD_PARAM(llvm::Type*, type);
CMD_PARAM(CmdParamVec<llvm::Constant*>, values);
SetResult(curId, llvm::ConstantArray::get((llvm::ArrayType*)type, values));
}
break;
case BfIRCmd_CreateConstString: case BfIRCmd_CreateConstString:
{ {
CMD_PARAM(String, str); CMD_PARAM(String, str);

View file

@ -1530,7 +1530,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId,
SizedArray<BfIRValue, 8> typeValueParams; SizedArray<BfIRValue, 8> typeValueParams;
GetConstClassValueParam(classVDataGlobal, typeValueParams); GetConstClassValueParam(classVDataGlobal, typeValueParams);
auto objData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(stringTypeInst->mBaseType, BfIRPopulateType_Full), typeValueParams); auto objData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(stringTypeInst->mBaseType, BfIRPopulateType_Full), typeValueParams);
auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize; auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize;
@ -1558,7 +1558,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId,
typeValueParams[fieldInstance->mDataIdx] = GetDefaultValue(fieldInstance->mResolvedType); typeValueParams[fieldInstance->mDataIdx] = GetDefaultValue(fieldInstance->mResolvedType);
} }
stringValData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(stringTypeInst, BfIRPopulateType_Full), typeValueParams); stringValData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(stringTypeInst, BfIRPopulateType_Full), typeValueParams);
} }
mBfIRBuilder->PopulateType(stringTypeInst); mBfIRBuilder->PopulateType(stringTypeInst);
@ -4823,7 +4823,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy
BfIRLinkageType_External, BfIRValue(), classVDataName); BfIRLinkageType_External, BfIRValue(), classVDataName);
BfIRType extVTableType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size()); BfIRType extVTableType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size());
BfIRValue extVTableConst = mBfIRBuilder->CreateConstArray(extVTableType, vData); BfIRValue extVTableConst = mBfIRBuilder->CreateConstAgg_Value(extVTableType, vData);
mBfIRBuilder->GlobalVar_SetInitializer(globalVariable, extVTableConst); mBfIRBuilder->GlobalVar_SetInitializer(globalVariable, extVTableConst);
mClassVDataExtRefs[mapEntry] = globalVariable; mClassVDataExtRefs[mapEntry] = globalVariable;
@ -4966,7 +4966,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
SizedArray<BfIRValue, 4> typeValueParams; SizedArray<BfIRValue, 4> typeValueParams;
GetConstClassValueParam(typeTypeData, typeValueParams); GetConstClassValueParam(typeTypeData, typeValueParams);
BfIRValue objectData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams); BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams);
StringT<128> typeDataName; StringT<128> typeDataName;
if ((typeInstance != NULL) && (!typeInstance->IsTypeAlias())) if ((typeInstance != NULL) && (!typeInstance->IsTypeAlias()))
@ -5078,7 +5078,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue(typeCode, byteType), // mTypeCode GetConstValue(typeCode, byteType), // mTypeCode
GetConstValue(type->mAlign, byteType), GetConstValue(type->mAlign, byteType),
}; };
auto typeData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType, BfIRPopulateType_Full), typeDataParams); auto typeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType, BfIRPopulateType_Full), typeDataParams);
if (typeInstance == NULL) if (typeInstance == NULL)
{ {
@ -5096,7 +5096,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
auto reflectPointerType = ResolveTypeDef(mCompiler->mReflectPointerType)->ToTypeInstance(); auto reflectPointerType = ResolveTypeDef(mCompiler->mReflectPointerType)->ToTypeInstance();
auto pointerTypeData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectPointerType, BfIRPopulateType_Full), pointerTypeDataParms); auto pointerTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectPointerType, BfIRPopulateType_Full), pointerTypeDataParms);
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectPointerType), true, typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectPointerType), true,
BfIRLinkageType_External, pointerTypeData, typeDataName); BfIRLinkageType_External, pointerTypeData, typeDataName);
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
@ -5113,7 +5113,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
auto reflectRefType = ResolveTypeDef(mCompiler->mReflectRefType)->ToTypeInstance(); auto reflectRefType = ResolveTypeDef(mCompiler->mReflectRefType)->ToTypeInstance();
auto refTypeData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectRefType, BfIRPopulateType_Full), refTypeDataParms); auto refTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectRefType, BfIRPopulateType_Full), refTypeDataParms);
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectRefType), true, typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectRefType), true,
BfIRLinkageType_External, refTypeData, typeDataName); BfIRLinkageType_External, refTypeData, typeDataName);
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
@ -5130,7 +5130,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
auto reflectSizedArrayType = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance(); auto reflectSizedArrayType = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance();
auto sizedArrayTypeData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectSizedArrayType, BfIRPopulateType_Full), sizedArrayTypeDataParms); auto sizedArrayTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectSizedArrayType, BfIRPopulateType_Full), sizedArrayTypeDataParms);
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectSizedArrayType), true, typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectSizedArrayType), true,
BfIRLinkageType_External, sizedArrayTypeData, typeDataName); BfIRLinkageType_External, sizedArrayTypeData, typeDataName);
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
@ -5663,7 +5663,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfIRLinkageType_External, BfIRValue(), classVDataName); BfIRLinkageType_External, BfIRValue(), classVDataName);
BfIRType extVTableType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)ifaceMethodExtData.size()); BfIRType extVTableType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)ifaceMethodExtData.size());
BfIRValue extVTableConst = mBfIRBuilder->CreateConstArray(extVTableType, ifaceMethodExtData); BfIRValue extVTableConst = mBfIRBuilder->CreateConstAgg_Value(extVTableType, ifaceMethodExtData);
mBfIRBuilder->GlobalVar_SetInitializer(ifaceMethodExtVar, extVTableConst); mBfIRBuilder->GlobalVar_SetInitializer(ifaceMethodExtVar, extVTableConst);
} }
@ -5764,7 +5764,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
// Fields // Fields
BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef); BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef);
BfIRValue emptyValueType = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray<BfIRValue, 1>()); BfIRValue emptyValueType = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray<BfIRValue, 1>());
auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes) auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes)
{ {
@ -5930,7 +5930,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
for (uint8 val : data) for (uint8 val : data)
dataValues.push_back(GetConstValue8(val)); dataValues.push_back(GetConstValue8(val));
auto dataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(byteType), (int)data.size()); auto dataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(byteType), (int)data.size());
auto customAttrConst = mBfIRBuilder->CreateConstArray(dataArrayType, dataValues); auto customAttrConst = mBfIRBuilder->CreateConstAgg_Value(dataArrayType, dataValues);
BfIRValue customAttrArray = mBfIRBuilder->CreateGlobalVariable(dataArrayType, true, BfIRLinkageType_Internal, BfIRValue customAttrArray = mBfIRBuilder->CreateGlobalVariable(dataArrayType, true, BfIRLinkageType_Internal,
customAttrConst, typeDataName + StrFormat(".customAttr%d", customAttrIdx)); customAttrConst, typeDataName + StrFormat(".customAttr%d", customAttrIdx));
@ -6039,7 +6039,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags
GetConstValue(-1, intType), // mCustomAttributesIdx GetConstValue(-1, intType), // mCustomAttributesIdx
}; };
auto payloadFieldData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), payloadFieldVals); auto payloadFieldData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), payloadFieldVals);
fieldTypes.push_back(payloadFieldData); fieldTypes.push_back(payloadFieldData);
} }
@ -6054,7 +6054,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags
GetConstValue(-1, intType), // mCustomAttributesIdx GetConstValue(-1, intType), // mCustomAttributesIdx
}; };
auto dscrFieldData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), dscrFieldVals); auto dscrFieldData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), dscrFieldVals);
fieldTypes.push_back(dscrFieldData); fieldTypes.push_back(dscrFieldData);
} }
@ -6132,7 +6132,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue(fieldFlags, shortType), // mFlags GetConstValue(fieldFlags, shortType), // mFlags
GetConstValue(customAttrIdx, intType), // mCustomAttributesIdx GetConstValue(customAttrIdx, intType), // mCustomAttributesIdx
}; };
auto fieldData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), fieldVals); auto fieldData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), fieldVals);
fieldTypes.push_back(fieldData); fieldTypes.push_back(fieldData);
} }
@ -6214,15 +6214,15 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
splatOffsets.Add(GetConstValue(0, intType)); splatOffsets.Add(GetConstValue(0, intType));
} }
BfIRValue splatTypesConst = mBfIRBuilder->CreateConstArray(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[0].mResolvedType), splatTypes); BfIRValue splatTypesConst = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[0].mResolvedType), splatTypes);
BfIRValue splatOffsetsConst = mBfIRBuilder->CreateConstArray(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[1].mResolvedType), splatOffsets); BfIRValue splatOffsetsConst = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[1].mResolvedType), splatOffsets);
SizedArray<BfIRValue, 8> splatVals = SizedArray<BfIRValue, 8> splatVals =
{ {
emptyValueType, emptyValueType,
splatTypesConst, splatTypesConst,
splatOffsetsConst splatOffsetsConst
}; };
auto fieldSplatData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldSplatDataType->ToTypeInstance(), BfIRPopulateType_Full), splatVals); auto fieldSplatData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldSplatDataType->ToTypeInstance(), BfIRPopulateType_Full), splatVals);
BfIRValue fieldDataArray = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(reflectFieldSplatDataType), true, BfIRLinkageType_Internal, BfIRValue fieldDataArray = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(reflectFieldSplatDataType), true, BfIRLinkageType_Internal,
fieldSplatData, typeDataName + ".splats"); fieldSplatData, typeDataName + ".splats");
@ -6234,7 +6234,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
else else
{ {
BfIRType fieldDataConstType = mBfIRBuilder->GetSizedArrayType(reflectFieldDataIRType, (int)fieldTypes.size()); BfIRType fieldDataConstType = mBfIRBuilder->GetSizedArrayType(reflectFieldDataIRType, (int)fieldTypes.size());
BfIRValue fieldDataConst = mBfIRBuilder->CreateConstArray(fieldDataConstType, fieldTypes); BfIRValue fieldDataConst = mBfIRBuilder->CreateConstAgg_Value(fieldDataConstType, fieldTypes);
BfIRValue fieldDataArray = mBfIRBuilder->CreateGlobalVariable(fieldDataConstType, true, BfIRLinkageType_Internal, BfIRValue fieldDataArray = mBfIRBuilder->CreateGlobalVariable(fieldDataConstType, true, BfIRLinkageType_Internal,
fieldDataConst, "fields." + typeDataName); fieldDataConst, "fields." + typeDataName);
fieldDataPtr = mBfIRBuilder->CreateBitCast(fieldDataArray, fieldDataPtrType); fieldDataPtr = mBfIRBuilder->CreateBitCast(fieldDataArray, fieldDataPtrType);
@ -6409,7 +6409,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue((int32)paramFlags, shortType), GetConstValue((int32)paramFlags, shortType),
GetConstValue(customAttrIdx, intType) // defaultIdx GetConstValue(customAttrIdx, intType) // defaultIdx
}; };
auto paramData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapType(reflectParamDataType, BfIRPopulateType_Full), paramDataVals); auto paramData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectParamDataType, BfIRPopulateType_Full), paramDataVals);
paramVals.Add(paramData); paramVals.Add(paramData);
} }
@ -6417,7 +6417,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if (paramVals.size() > 0) if (paramVals.size() > 0)
{ {
BfIRType paramDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(reflectParamDataType, BfIRPopulateType_Full), (int)paramVals.size()); BfIRType paramDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(reflectParamDataType, BfIRPopulateType_Full), (int)paramVals.size());
BfIRValue paramDataConst = mBfIRBuilder->CreateConstArray(paramDataArrayType, paramVals); BfIRValue paramDataConst = mBfIRBuilder->CreateConstAgg_Value(paramDataArrayType, paramVals);
BfIRValue paramDataArray = mBfIRBuilder->CreateGlobalVariable(paramDataArrayType, true, BfIRLinkageType_Internal, BfIRValue paramDataArray = mBfIRBuilder->CreateGlobalVariable(paramDataArrayType, true, BfIRLinkageType_Internal,
paramDataConst, typeDataName + StrFormat(".params%d", methodIdx)); paramDataConst, typeDataName + StrFormat(".params%d", methodIdx));
@ -6477,7 +6477,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue(vDataVal, intType), GetConstValue(vDataVal, intType),
GetConstValue(customAttrIdx, intType), GetConstValue(customAttrIdx, intType),
}; };
auto methodData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectMethodDataType->ToTypeInstance(), BfIRPopulateType_Full), methodDataVals); auto methodData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectMethodDataType->ToTypeInstance(), BfIRPopulateType_Full), methodDataVals);
methodTypes.push_back(methodData); methodTypes.push_back(methodData);
} }
@ -6488,7 +6488,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
else else
{ {
BfIRType methodDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(reflectMethodDataType, BfIRPopulateType_Full), (int)methodTypes.size()); BfIRType methodDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(reflectMethodDataType, BfIRPopulateType_Full), (int)methodTypes.size());
BfIRValue methodDataConst = mBfIRBuilder->CreateConstArray(methodDataArrayType, methodTypes); BfIRValue methodDataConst = mBfIRBuilder->CreateConstAgg_Value(methodDataArrayType, methodTypes);
BfIRValue methodDataArray = mBfIRBuilder->CreateGlobalVariable(methodDataArrayType, true, BfIRLinkageType_Internal, BfIRValue methodDataArray = mBfIRBuilder->CreateGlobalVariable(methodDataArrayType, true, BfIRLinkageType_Internal,
methodDataConst, "methods." + typeDataName); methodDataConst, "methods." + typeDataName);
methodDataPtr = mBfIRBuilder->CreateBitCast(methodDataArray, methodDataPtrType); methodDataPtr = mBfIRBuilder->CreateBitCast(methodDataArray, methodDataPtrType);
@ -6517,7 +6517,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
GetConstValue(interface.mStartVirtualIdx, intType), GetConstValue(interface.mStartVirtualIdx, intType),
}; };
auto interfaceData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectInterfaceDataType->ToTypeInstance(), BfIRPopulateType_Full), interfaceDataVals); auto interfaceData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectInterfaceDataType->ToTypeInstance(), BfIRPopulateType_Full), interfaceDataVals);
interfaces.push_back(interfaceData); interfaces.push_back(interfaceData);
for (int methodIdx = 0; methodIdx < (int)interface.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++) for (int methodIdx = 0; methodIdx < (int)interface.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
@ -6535,7 +6535,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
} }
BfIRType interfaceDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(reflectInterfaceDataType, BfIRPopulateType_Full), (int)interfaces.size()); BfIRType interfaceDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(reflectInterfaceDataType, BfIRPopulateType_Full), (int)interfaces.size());
BfIRValue interfaceDataConst = mBfIRBuilder->CreateConstArray(interfaceDataArrayType, interfaces); BfIRValue interfaceDataConst = mBfIRBuilder->CreateConstAgg_Value(interfaceDataArrayType, interfaces);
BfIRValue interfaceDataArray = mBfIRBuilder->CreateGlobalVariable(interfaceDataArrayType, true, BfIRLinkageType_Internal, BfIRValue interfaceDataArray = mBfIRBuilder->CreateGlobalVariable(interfaceDataArrayType, true, BfIRLinkageType_Internal,
interfaceDataConst, "interfaces." + typeDataName); interfaceDataConst, "interfaces." + typeDataName);
interfaceDataPtr = mBfIRBuilder->CreateBitCast(interfaceDataArray, interfaceDataPtrType); interfaceDataPtr = mBfIRBuilder->CreateBitCast(interfaceDataArray, interfaceDataPtrType);
@ -6575,7 +6575,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if (!methods.IsEmpty()) if (!methods.IsEmpty())
{ {
BfIRType methodDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(voidPtrType, BfIRPopulateType_Full), (int)methods.size()); BfIRType methodDataArrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(voidPtrType, BfIRPopulateType_Full), (int)methods.size());
BfIRValue methodDataConst = mBfIRBuilder->CreateConstArray(methodDataArrayType, methods); BfIRValue methodDataConst = mBfIRBuilder->CreateConstAgg_Value(methodDataArrayType, methods);
BfIRValue methodDataArray = mBfIRBuilder->CreateGlobalVariable(methodDataArrayType, true, BfIRLinkageType_Internal, BfIRValue methodDataArray = mBfIRBuilder->CreateGlobalVariable(methodDataArrayType, true, BfIRLinkageType_Internal,
methodDataConst, "imethods." + typeDataName); methodDataConst, "imethods." + typeDataName);
interfaceMethodTable = mBfIRBuilder->CreateBitCast(methodDataArray, voidPtrPtrIRType); interfaceMethodTable = mBfIRBuilder->CreateBitCast(methodDataArray, voidPtrPtrIRType);
@ -6606,7 +6606,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if (customAttrs.size() > 0) if (customAttrs.size() > 0)
{ {
BfIRType customAttrsArrayType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)customAttrs.size()); BfIRType customAttrsArrayType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)customAttrs.size());
BfIRValue customAttrsConst = mBfIRBuilder->CreateConstArray(customAttrsArrayType, customAttrs); BfIRValue customAttrsConst = mBfIRBuilder->CreateConstAgg_Value(customAttrsArrayType, customAttrs);
BfIRValue customAttrsArray = mBfIRBuilder->CreateGlobalVariable(customAttrsArrayType, true, BfIRLinkageType_Internal, BfIRValue customAttrsArray = mBfIRBuilder->CreateGlobalVariable(customAttrsArrayType, true, BfIRLinkageType_Internal,
customAttrsConst, "customAttrs." + typeDataName); customAttrsConst, "customAttrs." + typeDataName);
customAttrDataPtr = mBfIRBuilder->CreateBitCast(customAttrsArray, voidPtrPtrIRType); customAttrDataPtr = mBfIRBuilder->CreateBitCast(customAttrsArray, voidPtrPtrIRType);
@ -6649,7 +6649,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
BfIRType typeInstanceDataType = mBfIRBuilder->MapTypeInst(typeInstanceType->ToTypeInstance(), BfIRPopulateType_Full); BfIRType typeInstanceDataType = mBfIRBuilder->MapTypeInst(typeInstanceType->ToTypeInstance(), BfIRPopulateType_Full);
auto typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, typeDataVals); auto typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, typeDataVals);
if (!needsTypeData) if (!needsTypeData)
{ {
@ -6666,7 +6666,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
auto reflectUnspecializedGenericType = ResolveTypeDef(mCompiler->mReflectUnspecializedGenericType); auto reflectUnspecializedGenericType = ResolveTypeDef(mCompiler->mReflectUnspecializedGenericType);
typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectUnspecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full); typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectUnspecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full);
typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, unspecializedData); typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, unspecializedData);
} }
else if (typeInstance->IsGenericTypeInstance()) else if (typeInstance->IsGenericTypeInstance())
{ {
@ -6681,7 +6681,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
auto typeIRType = mBfIRBuilder->MapType(typeIdType); auto typeIRType = mBfIRBuilder->MapType(typeIdType);
auto typePtrIRType = mBfIRBuilder->GetPointerTo(typeIRType); auto typePtrIRType = mBfIRBuilder->GetPointerTo(typeIRType);
auto genericArrayType = mBfIRBuilder->GetSizedArrayType(typeIRType, (int)resolvedTypes.size()); auto genericArrayType = mBfIRBuilder->GetSizedArrayType(typeIRType, (int)resolvedTypes.size());
BfIRValue resolvedTypesConst = mBfIRBuilder->CreateConstArray(genericArrayType, resolvedTypes); BfIRValue resolvedTypesConst = mBfIRBuilder->CreateConstAgg_Value(genericArrayType, resolvedTypes);
BfIRValue resolvedTypesArray = mBfIRBuilder->CreateGlobalVariable(genericArrayType, true, BfIRLinkageType_Internal, BfIRValue resolvedTypesArray = mBfIRBuilder->CreateGlobalVariable(genericArrayType, true, BfIRLinkageType_Internal,
resolvedTypesConst, "resolvedTypes." + typeDataName); resolvedTypesConst, "resolvedTypes." + typeDataName);
BfIRValue resovledTypesPtr = mBfIRBuilder->CreateBitCast(resolvedTypesArray, typePtrIRType); BfIRValue resovledTypesPtr = mBfIRBuilder->CreateBitCast(resolvedTypesArray, typePtrIRType);
@ -6694,7 +6694,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectSpecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full); typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectSpecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full);
typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, specGenericData); typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, specGenericData);
if (typeInstance->IsArray()) if (typeInstance->IsArray())
{ {
@ -6712,7 +6712,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}; };
auto reflectArrayType = ResolveTypeDef(mCompiler->mReflectArrayType); auto reflectArrayType = ResolveTypeDef(mCompiler->mReflectArrayType);
typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectArrayType->ToTypeInstance(), BfIRPopulateType_Full); typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectArrayType->ToTypeInstance(), BfIRPopulateType_Full);
typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, arrayData); typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, arrayData);
} }
} }
@ -6742,7 +6742,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType); vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType);
auto classVDataConstDataType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size()); auto classVDataConstDataType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size());
auto classVDataConstData = mBfIRBuilder->CreateConstArray(classVDataConstDataType, vData); auto classVDataConstData = mBfIRBuilder->CreateConstAgg_Value(classVDataConstDataType, vData);
mBfIRBuilder->GlobalVar_SetInitializer(classVDataVar, classVDataConstData); mBfIRBuilder->GlobalVar_SetInitializer(classVDataVar, classVDataConstData);
if (mCompiler->mOptions.mObjectHasDebugFlags) if (mCompiler->mOptions.mObjectHasDebugFlags)
@ -8276,7 +8276,7 @@ BfIRValue BfModule::GetDbgRawAllocData(BfType* type)
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));
BfIRValue dataStruct = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapType(dbgRawAllocDataType, BfIRPopulateType_Full), dataValues); BfIRValue dataStruct = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(dbgRawAllocDataType, BfIRPopulateType_Full), dataValues);
allocDataValue = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(dbgRawAllocDataType), true, BfIRLinkageType_Internal, dataStruct, "__allocData_" + BfSafeMangler::Mangle(type)); allocDataValue = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(dbgRawAllocDataType), true, BfIRLinkageType_Internal, dataStruct, "__allocData_" + BfSafeMangler::Mangle(type));
mDbgRawAllocDataRefs.TryAdd(type, allocDataValue); mDbgRawAllocDataRefs.TryAdd(type, allocDataValue);
@ -8874,7 +8874,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef);
auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance())); auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance()));
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
{ {
SizedArray<BfIRValue, 4> llvmArgs; SizedArray<BfIRValue, 4> llvmArgs;
llvmArgs.push_back(vData); llvmArgs.push_back(vData);
@ -10367,9 +10367,9 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal)
return; return;
} }
if (constant->mConstType == BfConstType_Array) if (constant->mConstType == BfConstType_Agg)
{ {
auto constArray = (BfConstantArray*)constant; auto constArray = (BfConstantAgg*)constant;
SizedArray<BfIRValue, 8> newVals; SizedArray<BfIRValue, 8> newVals;
for (auto val : constArray->mValues) for (auto val : constArray->mValues)
@ -10379,7 +10379,7 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal)
newVals.push_back(newVal); newVals.push_back(newVal);
} }
irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstArray(constArray->mType, newVals); irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstAgg(constArray->mType, newVals);
return; return;
} }
@ -10485,6 +10485,12 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
{ {
if (constant->mTypeCode == BfTypeCode_NullPtr) if (constant->mTypeCode == BfTypeCode_NullPtr)
{ {
if ((wantType == NULL) && (constant->mIRType.mKind == BfIRTypeData::TypeKind_TypeId))
wantType = mContext->mTypes[constant->mIRType.mId];
if (wantType == NULL)
return constHolder->CreateConstNull();
return GetDefaultValue(wantType); return GetDefaultValue(wantType);
} }
@ -10501,18 +10507,49 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
} }
} }
if (constant->mConstType == BfConstType_Array) if (constant->mConstType == BfConstType_Agg)
{ {
auto elementType = wantType->GetUnderlyingType(); auto constArray = (BfConstantAgg*)constant;
auto constArray = (BfConstantArray*)constant;
if ((wantType == NULL) && (constArray->mType.mKind == BfIRTypeData::TypeKind_TypeId))
wantType = mContext->mTypes[constArray->mType.mId];
SizedArray<BfIRValue, 8> newVals; SizedArray<BfIRValue, 8> newVals;
if (wantType->IsSizedArray())
{
auto elementType = wantType->GetUnderlyingType();
for (auto val : constArray->mValues) for (auto val : constArray->mValues)
{ {
newVals.push_back(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType)); newVals.Add(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType));
}
}
else
{
auto wantTypeInst = wantType->ToTypeInstance();
if (wantTypeInst->mBaseType != NULL)
{
auto baseVal = ConstantToCurrent(constHolder->GetConstant(constArray->mValues[0]), constHolder, wantTypeInst->mBaseType);
newVals.Add(baseVal);
} }
return mBfIRBuilder->CreateConstArray(mBfIRBuilder->MapType(wantType), newVals); for (auto& fieldInstance : wantTypeInst->mFieldInstances)
{
if (fieldInstance.mDataIdx < 0)
continue;
auto val = constArray->mValues[fieldInstance.mDataIdx];
BfIRValue memberVal = ConstantToCurrent(constHolder->GetConstant(val), constHolder, fieldInstance.mResolvedType);
if (fieldInstance.mDataIdx == newVals.mSize)
newVals.Add(memberVal);
else
{
while (fieldInstance.mDataIdx >= newVals.mSize)
newVals.Add(BfIRValue());
newVals[fieldInstance.mDataIdx] = memberVal;
}
}
}
return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(wantType), newVals);
} }
return mBfIRBuilder->CreateConst(constant, constHolder); return mBfIRBuilder->CreateConst(constant, constHolder);
@ -11290,6 +11327,17 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo
return BfTypedValue(loadedVal, typedValue.mType, false); return BfTypedValue(loadedVal, typedValue.mType, false);
} }
BfTypedValue BfModule::PrepareConst(BfTypedValue& typedValue)
{
if (!typedValue.mValue.IsConst())
return typedValue;
auto constant = mBfIRBuilder->GetConstant(typedValue.mValue);
if (constant->mTypeCode == BfTypeCode_StringId)
return GetTypedValueFromConstant(constant, mBfIRBuilder, typedValue.mType);
return typedValue;
}
BfTypedValue BfModule::LoadOrAggregateValue(BfTypedValue typedValue) BfTypedValue BfModule::LoadOrAggregateValue(BfTypedValue typedValue)
{ {
if (typedValue.IsSplat()) if (typedValue.IsSplat())
@ -11303,6 +11351,7 @@ BfTypedValue BfModule::AggregateSplat(BfTypedValue typedValue, BfIRValue* valueA
{ {
if (!typedValue.IsSplat()) if (!typedValue.IsSplat())
return typedValue; return typedValue;
BF_ASSERT(!mIsConstModule);
if (typedValue.mType->IsValuelessType()) if (typedValue.mType->IsValuelessType())
return typedValue; return typedValue;
@ -11399,6 +11448,8 @@ void BfModule::AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal
if (typedValue.mType->IsValuelessType()) if (typedValue.mType->IsValuelessType())
return; return;
BF_ASSERT(!mIsConstModule);
/*static int sCallIdx = 0; /*static int sCallIdx = 0;
if (!mCompiler->mIsResolveOnly) if (!mCompiler->mIsResolveOnly)
sCallIdx++; sCallIdx++;
@ -11523,6 +11574,8 @@ BfTypedValue BfModule::RemoveReadOnly(BfTypedValue typedValue)
BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, BfType* wantType, bool* isAddr) BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, BfType* wantType, bool* isAddr)
{ {
BF_ASSERT(!mIsConstModule);
BfIRValue val; BfIRValue val;
if (typedValue.mValue.IsArg()) if (typedValue.mValue.IsArg())
{ {
@ -13510,7 +13563,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
isConstant = isConstant =
(constant->mConstType < BfConstType_GlobalVar) || (constant->mConstType < BfConstType_GlobalVar) ||
(constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_AggZero) ||
(constant->mConstType == BfConstType_Array); (constant->mConstType == BfConstType_Agg);
if (isConstant) if (isConstant)
{ {
if (localVarDef->mResolvedType->IsComposite()) if (localVarDef->mResolvedType->IsComposite())
@ -13639,7 +13692,7 @@ void BfModule::CreateDIRetVal()
{ {
BfType* dbgType = mCurMethodInstance->mReturnType; BfType* dbgType = mCurMethodInstance->mReturnType;
BfIRValue dbgValue = mCurMethodState->mRetVal.mValue; BfIRValue dbgValue = mCurMethodState->mRetVal.mValue;
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
{ {
BF_ASSERT(mCurMethodState->mRetValAddr); BF_ASSERT(mCurMethodState->mRetValAddr);
dbgType = CreatePointerType(dbgType); dbgType = CreatePointerType(dbgType);
@ -14255,7 +14308,7 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData)
void BfModule::CreateReturn(BfIRValue val) void BfModule::CreateReturn(BfIRValue val)
{ {
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
{ {
// Store to sret // Store to sret
BF_ASSERT(val); BF_ASSERT(val);
@ -14274,6 +14327,7 @@ void BfModule::CreateReturn(BfIRValue val)
{ {
BfTypeCode loweredReturnType = BfTypeCode_None; BfTypeCode loweredReturnType = BfTypeCode_None;
BfTypeCode loweredReturnType2 = BfTypeCode_None; BfTypeCode loweredReturnType2 = BfTypeCode_None;
if (!mIsConstModule)
mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2); mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2);
if (loweredReturnType != BfTypeCode_None) if (loweredReturnType != BfTypeCode_None)
@ -14341,7 +14395,7 @@ void BfModule::EmitDefaultReturn()
{ {
if (mCurMethodInstance->mReturnType->IsVoid()) if (mCurMethodInstance->mReturnType->IsVoid())
mBfIRBuilder->CreateRetVoid(); mBfIRBuilder->CreateRetVoid();
else if (mCurMethodInstance->GetStructRetIdx() == -1) else if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() == -1))
mBfIRBuilder->CreateRet(GetDefaultValue(mCurMethodInstance->mReturnType)); mBfIRBuilder->CreateRet(GetDefaultValue(mCurMethodInstance->mReturnType));
} }
@ -14450,18 +14504,18 @@ void BfModule::CreateDelegateInvokeMethod()
if (mCurMethodInstance->mReturnType->IsValueType()) if (mCurMethodInstance->mReturnType->IsValueType())
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full); mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full);
if (mCurMethodInstance->GetStructRetIdx() != 0) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != 0))
memberFuncArgs.push_back(BfIRValue()); // Push 'target' memberFuncArgs.push_back(BfIRValue()); // Push 'target'
int thisIdx = 0; int thisIdx = 0;
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
{ {
thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1;
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
} }
if (mCurMethodInstance->GetStructRetIdx() == 0) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() == 0))
memberFuncArgs.push_back(BfIRValue()); // Push 'target' memberFuncArgs.push_back(BfIRValue()); // Push 'target'
mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true); mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true);
@ -14500,7 +14554,7 @@ void BfModule::CreateDelegateInvokeMethod()
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr); auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr);
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr); auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs); nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs);
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
mBfIRBuilder->Call_AddAttribute(nonStaticResult, mCurMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); mBfIRBuilder->Call_AddAttribute(nonStaticResult, mCurMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
if (callingConv != BfIRCallingConv_CDecl) if (callingConv != BfIRCallingConv_CDecl)
mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv); mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv);
@ -14518,7 +14572,7 @@ void BfModule::CreateDelegateInvokeMethod()
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr); auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr);
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr); auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs); staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs);
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
{ {
// Note: since this is a forced static invocation, we know the sret will be the first parameter // Note: since this is a forced static invocation, we know the sret will be the first parameter
mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet); mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet);
@ -14535,7 +14589,8 @@ void BfModule::CreateDelegateInvokeMethod()
mBfIRBuilder->AddBlock(doneBB); mBfIRBuilder->AddBlock(doneBB);
mBfIRBuilder->SetInsertPoint(doneBB); mBfIRBuilder->SetInsertPoint(doneBB);
if ((mCurMethodInstance->mReturnType->IsValuelessType()) || (mCurMethodInstance->GetStructRetIdx() != -1)) if ((mCurMethodInstance->mReturnType->IsValuelessType()) ||
((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)))
{ {
mBfIRBuilder->CreateRetVoid(); mBfIRBuilder->CreateRetVoid();
} }
@ -14544,7 +14599,7 @@ void BfModule::CreateDelegateInvokeMethod()
BfIRType loweredIRReturnType; BfIRType loweredIRReturnType;
BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (mCurMethodInstance->GetLoweredReturnType(&loweredTypeCode, &loweredTypeCode2)) if ((!mIsConstModule) && (mCurMethodInstance->GetLoweredReturnType(&loweredTypeCode, &loweredTypeCode2)))
loweredIRReturnType = GetIRLoweredType(loweredTypeCode, loweredTypeCode2); loweredIRReturnType = GetIRLoweredType(loweredTypeCode, loweredTypeCode2);
else else
loweredIRReturnType = mBfIRBuilder->MapType(mCurMethodInstance->mReturnType); loweredIRReturnType = mBfIRBuilder->MapType(mCurMethodInstance->mReturnType);
@ -14624,7 +14679,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr
int argCount = 0; int argCount = 0;
if (!paramType->IsValuelessType()) if (!paramType->IsValuelessType())
{ {
if (methodInst->GetParamIsSplat(paramIdx)) if ((!mIsConstModule) && (methodInst->GetParamIsSplat(paramIdx)))
argCount = paramType->GetSplatCount(); argCount = paramType->GetSplatCount();
else else
argCount = 1; argCount = 1;
@ -15449,7 +15504,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
while (argIdx < argCount) while (argIdx < argCount)
{ {
if (argIdx == methodInstance->GetStructRetIdx()) if ((!mIsConstModule) && (argIdx == methodInstance->GetStructRetIdx()))
{ {
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoAlias); mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoAlias);
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_StructRet); mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_StructRet);
@ -15473,8 +15528,8 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
resolvedTypeRef = mCurMethodState->mClosureState->mClosureType; resolvedTypeRef = mCurMethodState->mClosureState->mClosureType;
else else
resolvedTypeRef = methodInstance->GetThisType(); resolvedTypeRef = methodInstance->GetThisType();
isSplattable = (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting()); isSplattable = (!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting());
tryLowering = methodInstance->AllowsThisSplatting(); tryLowering = (!mIsConstModule) && (methodInstance->AllowsThisSplatting());
} }
else else
{ {
@ -15482,7 +15537,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
resolvedTypeRef = methodInstance->GetParamType(paramIdx); resolvedTypeRef = methodInstance->GetParamType(paramIdx);
if (resolvedTypeRef->IsMethodRef()) if (resolvedTypeRef->IsMethodRef())
isSplattable = true; isSplattable = true;
else if ((resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting())) else if ((!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting()))
{ {
auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance(); auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance();
if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr)) if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr))
@ -16620,7 +16675,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
int argIdx = 0; int argIdx = 0;
if (argIdx == methodInstance->GetStructRetIdx()) if ((!mIsConstModule) && (argIdx == methodInstance->GetStructRetIdx()))
argIdx++; argIdx++;
if (!methodDef->mIsStatic) if (!methodDef->mIsStatic)
@ -16636,12 +16691,12 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
else else
paramVar->mValue = mBfIRBuilder->GetFakeVal(); paramVar->mValue = mBfIRBuilder->GetFakeVal();
if ((thisType->IsSplattable()) && (methodInstance->AllowsThisSplatting())) if ((!mIsConstModule) && (thisType->IsSplattable()) && (methodInstance->AllowsThisSplatting()))
{ {
if (!thisType->IsTypedPrimitive()) if (!thisType->IsTypedPrimitive())
paramVar->mIsSplat = true; paramVar->mIsSplat = true;
} }
else if ((!methodDef->mIsMutating) && (methodInstance->mCallingConvention == BfCallingConvention_Unspecified)) else if ((!mIsConstModule) && (!methodDef->mIsMutating) && (methodInstance->mCallingConvention == BfCallingConvention_Unspecified))
paramVar->mIsLowered = thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None; paramVar->mIsLowered = thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None;
auto thisTypeInst = thisType->ToTypeInstance(); auto thisTypeInst = thisType->ToTypeInstance();
@ -16690,7 +16745,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
} }
} }
if (argIdx == methodInstance->GetStructRetIdx()) if ((!mIsConstModule) && (argIdx == methodInstance->GetStructRetIdx()))
argIdx++; argIdx++;
bool hadParams = false; bool hadParams = false;
@ -16730,7 +16785,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
} }
else if (resolvedType->IsComposite() && resolvedType->IsSplattable()) else if (resolvedType->IsComposite() && resolvedType->IsSplattable())
{ {
if (methodInstance->AllowsSplatting()) if ((!mIsConstModule) && (methodInstance->AllowsSplatting()))
{ {
int splatCount = resolvedType->GetSplatCount(); int splatCount = resolvedType->GetSplatCount();
if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs) if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs)
@ -16744,7 +16799,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
paramVar->mValue = mBfIRBuilder->GetFakeVal(); paramVar->mValue = mBfIRBuilder->GetFakeVal();
} }
paramVar->mIsLowered = resolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None; paramVar->mIsLowered = (!mIsConstModule) && resolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None;
paramVar->mIsStruct = resolvedType->IsComposite() && !resolvedType->IsTypedPrimitive(); paramVar->mIsStruct = resolvedType->IsComposite() && !resolvedType->IsTypedPrimitive();
paramVar->mParamIdx = paramIdx; paramVar->mParamIdx = paramIdx;
paramVar->mIsImplicitParam = methodInstance->IsImplicitCapture(paramIdx); paramVar->mIsImplicitParam = methodInstance->IsImplicitCapture(paramIdx);
@ -17291,7 +17346,7 @@ void BfModule::EmitGCMarkMembers()
auto baseValue = Cast(NULL, thisValue, methodBaseType, BfCastFlags_Explicit); auto baseValue = Cast(NULL, thisValue, methodBaseType, BfCastFlags_Explicit);
SizedArray<BfIRValue, 1> args; SizedArray<BfIRValue, 1> args;
if (moduleMethodInst.mMethodInstance->GetParamIsSplat(-1)) if ((!mIsConstModule) && (moduleMethodInst.mMethodInstance->GetParamIsSplat(-1)))
{ {
BfExprEvaluator exprEvaluator(this); BfExprEvaluator exprEvaluator(this);
exprEvaluator.SplatArgs(baseValue, args); exprEvaluator.SplatArgs(baseValue, args);
@ -17945,7 +18000,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
flags |= llvm::DINode::FlagStaticMember; flags |= llvm::DINode::FlagStaticMember;
else else
{ {
if ((mCurTypeInstance->IsValuelessType()) || (mCurTypeInstance->IsSplattable())) if ((mCurTypeInstance->IsValuelessType()) ||
((!mIsConstModule) && (mCurTypeInstance->IsSplattable())))
flags |= llvm::DINode::FlagStaticMember; flags |= llvm::DINode::FlagStaticMember;
} }
flags |= llvm::DINode::FlagPrototyped; flags |= llvm::DINode::FlagPrototyped;
@ -18095,7 +18151,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
if ((isThis) && (thisType->IsValuelessType())) if ((isThis) && (thisType->IsValuelessType()))
isThis = false; isThis = false;
if (methodInstance->GetStructRetIdx() == argIdx) if ((!mIsConstModule) && (methodInstance->GetStructRetIdx() == argIdx))
{ {
argIdx++; argIdx++;
if (argIdx == irParamCount) if (argIdx == irParamCount)
@ -18118,7 +18174,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
paramVar->mIsReadOnly = true; paramVar->mIsReadOnly = true;
} }
bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter)); bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) ||
((!mIsConstModule) && (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter)));
if (paramVar->mResolvedType->IsMethodRef()) if (paramVar->mResolvedType->IsMethodRef())
wantsAddr = false; wantsAddr = false;
@ -18259,7 +18316,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
int splatAddrIdx = 0; int splatAddrIdx = 0;
while (localIdx < (int)methodState.mLocals.size()) while (localIdx < (int)methodState.mLocals.size())
{ {
if (argIdx == methodInstance->GetStructRetIdx()) if ((!mIsConstModule) && (argIdx == methodInstance->GetStructRetIdx()))
argIdx++; argIdx++;
int curLocalIdx = localIdx++; int curLocalIdx = localIdx++;
@ -18695,7 +18752,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{ {
BF_ASSERT(innerType->IsUnspecializedType()); BF_ASSERT(innerType->IsUnspecializedType());
} }
else if (methodInstance->GetStructRetIdx() != -1) else if ((!mIsConstModule) && (methodInstance->GetStructRetIdx() != -1))
{ {
mBfIRBuilder->PopulateType(methodInstance->mReturnType); mBfIRBuilder->PopulateType(methodInstance->mReturnType);
auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true); auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true);
@ -19071,7 +19128,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{ {
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType); mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType);
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
{ {
auto ptrType = CreatePointerType(mCurMethodInstance->mReturnType); auto ptrType = CreatePointerType(mCurMethodInstance->mReturnType);
auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false); auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false);
@ -19264,7 +19321,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
if (mCurMethodState->mIRExitBlock) if (mCurMethodState->mIRExitBlock)
{ {
if ((mCurMethodState->mRetVal) && (mCurMethodInstance->GetStructRetIdx() == -1)) if ((mCurMethodState->mRetVal) &&
((mIsConstModule) || (mCurMethodInstance->GetStructRetIdx() == -1)))
{ {
auto loadedVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetVal.mValue); auto loadedVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetVal.mValue);
@ -19303,7 +19361,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{ {
if ((!mCurMethodState->mHadReturn) && (!mCurMethodState->mIRExitBlock)) if ((!mCurMethodState->mHadReturn) && (!mCurMethodState->mIRExitBlock))
{ {
if ((irParamCount == 0) && (!IsTargetingBeefBackend()) && (mCompiler->mOptions.mAllowHotSwapping)) if ((!mIsConstModule) && (irParamCount == 0) && (!IsTargetingBeefBackend()) && (mCompiler->mOptions.mAllowHotSwapping))
{ {
// This may be a case where we only emit 4 bytes, whereas we need 5 for a hot replace jump // This may be a case where we only emit 4 bytes, whereas we need 5 for a hot replace jump
mBfIRBuilder->EnsureFunctionPatchable(); mBfIRBuilder->EnsureFunctionPatchable();
@ -19347,7 +19405,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{ {
// If we hot swap, we want to make sure at least one method refers to this extern method so it gets pulled in // If we hot swap, we want to make sure at least one method refers to this extern method so it gets pulled in
// incase it gets called later by some hot-loaded coded // incase it gets called later by some hot-loaded coded
if ((mCompiler->mOptions.mAllowHotSwapping) && (mCurMethodInstance->mIRFunction) && (!mCurMethodInstance->mIRFunction.IsFake())) if ((mCompiler->mOptions.mAllowHotSwapping) && (mCurMethodInstance->mIRFunction) && (!mCurMethodInstance->mIRFunction.IsFake()) && (mCurTypeInstance != mContext->mBfObjectType))
CreateFakeCallerMethod(mangledName); CreateFakeCallerMethod(mangledName);
mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
} }
@ -21405,7 +21463,7 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
{ {
BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (!methodDef->mIsMutating) if ((!mIsConstModule) && (!methodDef->mIsMutating))
thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2); thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2);
argIdx++; argIdx++;
if (loweredTypeCode2 != BfTypeCode_None) if (loweredTypeCode2 != BfTypeCode_None)
@ -21413,7 +21471,7 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
} }
} }
if (methodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (methodInstance->GetStructRetIdx() != -1))
argIdx++; argIdx++;
for (int paramIdx = 0; paramIdx < mCurMethodInstance->mParams.size(); paramIdx++) for (int paramIdx = 0; paramIdx < mCurMethodInstance->mParams.size(); paramIdx++)
@ -21449,6 +21507,7 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
{ {
BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode = BfTypeCode_None;
BfTypeCode loweredTypeCode2 = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None;
if (!mIsConstModule)
checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2); checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2);
argIdx++; argIdx++;
if (loweredTypeCode2 != BfTypeCode_None) if (loweredTypeCode2 != BfTypeCode_None)

View file

@ -1593,6 +1593,7 @@ public:
BfTypedValue RemoveRef(BfTypedValue typedValue); BfTypedValue RemoveRef(BfTypedValue typedValue);
BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue); BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue);
BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false); BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false);
BfTypedValue PrepareConst(BfTypedValue& typedValue);
void AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal); void AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal);
BfTypedValue AggregateSplat(BfTypedValue typedValue, BfIRValue* valueArrPtr = NULL); BfTypedValue AggregateSplat(BfTypedValue typedValue, BfIRValue* valueArrPtr = NULL);
BfTypedValue MakeAddressable(BfTypedValue typedValue); BfTypedValue MakeAddressable(BfTypedValue typedValue);

View file

@ -5328,6 +5328,8 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2) BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
{ {
BF_ASSERT(!mIsConstModule);
BF_ASSERT(loweredTypeCode != BfTypeCode_None); BF_ASSERT(loweredTypeCode != BfTypeCode_None);
if (loweredTypeCode2 == BfTypeCode_None) if (loweredTypeCode2 == BfTypeCode_None)
return mBfIRBuilder->GetPrimitiveType(loweredTypeCode); return mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
@ -10763,12 +10765,41 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
} }
} }
if ((typedVal.mValue.IsConst()) && (toType->IsPointer()) && (toType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) && (typedVal.mType->IsInstanceOf(mCompiler->mStringTypeDef))) if (typedVal.mValue.IsConst())
{
if ((toType->IsPointer()) && (toType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) && (typedVal.mType->IsInstanceOf(mCompiler->mStringTypeDef)))
{ {
int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder); int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder);
if (stringId >= 0) if (stringId >= 0)
return GetStringCharPtr(stringId); return GetStringCharPtr(stringId);
} }
else if ((toType->IsInstanceOf(mCompiler->mStringViewTypeDef)))
{
int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder);
if (stringId >= 0)
{
int strLen = 0;
String str;
BfStringPoolEntry* entry = NULL;
if (mContext->mStringObjectIdMap.TryGetValue(stringId, &entry))
{
auto svTypeInst = toType->ToTypeInstance();
mBfIRBuilder->PopulateType(svTypeInst);
auto stringCharPtr = GetStringCharPtr(stringId);
SizedArray<BfIRValue, 2> spanFieldVals;
spanFieldVals.Add(mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(svTypeInst->mBaseType->mBaseType)));
spanFieldVals.Add(stringCharPtr);
spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, entry->mString.mLength));
SizedArray<BfIRValue, 2> svFieldVals;
svFieldVals.Add(mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst->mBaseType), spanFieldVals));
return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst), svFieldVals);
}
}
}
}
// Check user-defined operators // Check user-defined operators
if ((castFlags & BfCastFlags_NoConversionOperator) == 0) if ((castFlags & BfCastFlags_NoConversionOperator) == 0)
@ -11275,6 +11306,15 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf
PopulateType(toType, ((castFlags & BfCastFlags_NoConversionOperator) != 0) ? BfPopulateType_Data : BfPopulateType_DataAndMethods); PopulateType(toType, ((castFlags & BfCastFlags_NoConversionOperator) != 0) ? BfPopulateType_Data : BfPopulateType_DataAndMethods);
if ((toType->IsSizedArray()) && (typedVal.mType->IsSizedArray()))
{
// Retain our type if we're casting from a known-sized array to an unknown-sized arrays
if ((toType->IsUndefSizedArray()) && ((typedVal.mType->GetUnderlyingType()) == (toType->GetUnderlyingType())))
{
return typedVal;
}
}
if ((castFlags & BfCastFlags_Force) != 0) if ((castFlags & BfCastFlags_Force) != 0)
{ {
if (toType->IsValuelessType()) if (toType->IsValuelessType())
@ -11575,11 +11615,11 @@ BfTypedValue BfModule::GetIntCoercible(const BfTypedValue& typedValue)
if (typedValue.mValue.IsConst()) if (typedValue.mValue.IsConst())
{ {
auto constant = mBfIRBuilder->GetConstant(typedValue.mValue); auto constant = mBfIRBuilder->GetConstant(typedValue.mValue);
if (constant->mConstType == BfConstType_Array) if (constant->mConstType == BfConstType_Agg)
{ {
uint64 intVal = 0; uint64 intVal = 0;
auto constantArray = (BfConstantArray*)constant; auto constantArray = (BfConstantAgg*)constant;
int memberIdx = 0; int memberIdx = 0;
for (int memberIdx = 0; memberIdx < (int)constantArray->mValues.size(); memberIdx++) for (int memberIdx = 0; memberIdx < (int)constantArray->mValues.size(); memberIdx++)
{ {

View file

@ -1096,7 +1096,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
BfTypeCode loweredReturnTypeCode = BfTypeCode_None; BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None; BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
if (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)) if ((!module->mIsConstModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)))
{ {
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2); auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
returnType = irReturnType; returnType = irReturnType;
@ -1106,7 +1106,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
auto voidType = module->GetPrimitiveType(BfTypeCode_None); auto voidType = module->GetPrimitiveType(BfTypeCode_None);
returnType = module->mBfIRBuilder->MapType(voidType); returnType = module->mBfIRBuilder->MapType(voidType);
} }
else if (GetStructRetIdx(forceStatic) != -1) else if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) != -1))
{ {
auto voidType = module->GetPrimitiveType(BfTypeCode_None); auto voidType = module->GetPrimitiveType(BfTypeCode_None);
returnType = module->mBfIRBuilder->MapType(voidType); returnType = module->mBfIRBuilder->MapType(voidType);
@ -1126,8 +1126,6 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
returnType = module->mBfIRBuilder->MapType(mReturnType); returnType = module->mBfIRBuilder->MapType(mReturnType);
} }
for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++) for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++)
{ {
BfType* checkType = NULL; BfType* checkType = NULL;
@ -1161,11 +1159,15 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
bool doSplat = false; bool doSplat = false;
if (paramIdx == -1) if (paramIdx == -1)
{ {
if ((checkType->IsSplattable()) && (AllowsThisSplatting())) if ((!mMethodDef->mIsMutating) && (checkType->IsTypedPrimitive()))
{
checkType = checkType->GetUnderlyingType();
}
else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsThisSplatting()))
{ {
doSplat = true; doSplat = true;
} }
else if ((!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified)) else if ((!module->mIsConstModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified))
checkLowered = true; checkLowered = true;
} }
else else
@ -1174,11 +1176,15 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
{ {
doSplat = true; doSplat = true;
} }
else if ((checkType->IsSplattable()) && (AllowsSplatting())) else if (checkType->IsTypedPrimitive())
{
checkType = checkType->GetUnderlyingType();
}
else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting()))
{ {
doSplat = true; doSplat = true;
} }
else else if (!module->mIsConstModule)
checkLowered = true; checkLowered = true;
} }
@ -1258,7 +1264,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
paramIdx++; // Skip over the explicit 'this' paramIdx++; // Skip over the explicit 'this'
} }
if (GetStructRetIdx(forceStatic) == 1) if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) == 1))
{ {
BF_SWAP(paramTypes[0], paramTypes[1]); BF_SWAP(paramTypes[0], paramTypes[1]);
} }
@ -3082,7 +3088,12 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
if (typedVal) if (typedVal)
{ {
auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue); auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
if (constant->mConstType == BfConstType_Undef) if (constant == NULL)
{
ctx->mFailed = true;
ctx->mModule->Fail("Array size not a constant value", arrayType->mParams[0]);
}
else if (constant->mConstType == BfConstType_Undef)
{ {
elementCount = -1; // Marker for undef elementCount = -1; // Marker for undef
} }

View file

@ -528,6 +528,7 @@ public:
virtual bool IsObjectOrInterface() { return false; } virtual bool IsObjectOrInterface() { return false; }
virtual bool IsString() { return false; } virtual bool IsString() { return false; }
virtual bool IsSizedArray() { return false; } virtual bool IsSizedArray() { return false; }
virtual bool IsUndefSizedArray() { return false; }
virtual bool IsUnknownSizedArray() { return false; } virtual bool IsUnknownSizedArray() { return false; }
virtual bool IsArray() { return false; } virtual bool IsArray() { return false; }
virtual bool IsDelegate() { return false; } virtual bool IsDelegate() { return false; }
@ -2277,6 +2278,7 @@ public:
virtual bool NeedsExplicitAlignment() override { return mElementType->NeedsExplicitAlignment(); } virtual bool NeedsExplicitAlignment() override { return mElementType->NeedsExplicitAlignment(); }
virtual bool IsSizedArray() override { return true; } virtual bool IsSizedArray() override { return true; }
virtual bool IsUndefSizedArray() override { return mElementCount == -1; }
virtual bool IsWrappableType() override { return true; } virtual bool IsWrappableType() override { return true; }
virtual bool IsValueType() override { return true; } // Is a type of struct virtual bool IsValueType() override { return true; } // Is a type of struct

View file

@ -1595,9 +1595,6 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
} }
}; };
PopulateType(resolvedType);
AddDependency(resolvedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
localDef->mResolvedType = resolvedType; localDef->mResolvedType = resolvedType;
localDef->mIsReadOnly = isReadOnly; localDef->mIsReadOnly = isReadOnly;
@ -1658,6 +1655,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId); initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId);
if (!initValue) if (!initValue)
initValue = GetDefaultTypedValue(resolvedType); initValue = GetDefaultTypedValue(resolvedType);
} }
else if (varDecl->mInitializer->IsA<BfUninitializedExpression>()) else if (varDecl->mInitializer->IsA<BfUninitializedExpression>())
{ {
@ -1680,15 +1678,12 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
if ((!handledVarInit) && (initValue)) if ((!handledVarInit) && (initValue))
initValue = Cast(varDecl->mInitializer, initValue, resolvedType, BfCastFlags_PreferAddr); initValue = Cast(varDecl->mInitializer, initValue, resolvedType, BfCastFlags_PreferAddr);
}
// Why did we remove this? if ((initValue) && (resolvedType->IsUndefSizedArray()))
// if ((valExprEvaluator.mResultIsTempComposite) && (initValue.IsAddr())) {
// { resolvedType = initValue.mType;
// BF_ASSERT(initValue.mType->IsComposite()); unresolvedType = resolvedType;
// localDef->mAddr = initValue.mValue;
// handledVarInit = true;
// handledVarStore = true;
// }
} }
} }
if ((!handledVarInit) && (!isConst)) if ((!handledVarInit) && (!isConst))
@ -1728,10 +1723,15 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
} }
else else
{ {
BF_ASSERT(!localDef->mResolvedType->IsRef()); BF_ASSERT(!resolvedType->IsRef());
} }
} }
PopulateType(resolvedType);
AddDependency(resolvedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
localDef->mResolvedType = resolvedType;
_CheckConst(); _CheckConst();
if ((initValue.mKind == BfTypedValueKind_TempAddr) && (!initHandled)) if ((initValue.mKind == BfTypedValueKind_TempAddr) && (!initHandled))
@ -1771,6 +1771,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
initValue = LoadValue(initValue); initValue = LoadValue(initValue);
if (initValue.IsSplat()) if (initValue.IsSplat())
{ {
BF_ASSERT(!mIsConstModule);
if (!localDef->mAddr) if (!localDef->mAddr)
localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName); localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName);
AggregateSplatIntoAddr(initValue, localDef->mAddr); AggregateSplatIntoAddr(initValue, localDef->mAddr);
@ -4945,12 +4946,12 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
BfType* origType; BfType* origType;
BfExprEvaluator exprEvaluator(this); BfExprEvaluator exprEvaluator(this);
bool alreadyWritten = false; bool alreadyWritten = false;
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal; exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal;
if (mCurMethodInstance->mMethodDef->mIsReadOnly) if (mCurMethodInstance->mMethodDef->mIsReadOnly)
exprEvaluator.mAllowReadOnlyReference = true; exprEvaluator.mAllowReadOnlyReference = true;
auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType); auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType);
if (mCurMethodInstance->GetStructRetIdx() != -1) if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))
alreadyWritten = exprEvaluator.mReceivingValue == NULL; alreadyWritten = exprEvaluator.mReceivingValue == NULL;
MarkScopeLeft(&mCurMethodState->mHeadScope); MarkScopeLeft(&mCurMethodState->mHeadScope);

File diff suppressed because it is too large Load diff

View file

@ -55,6 +55,7 @@ typedef int addr_ce;
enum CeErrorKind enum CeErrorKind
{ {
CeErrorKind_None, CeErrorKind_None,
CeErrorKind_Error,
CeErrorKind_GlobalVariable, CeErrorKind_GlobalVariable,
CeErrorKind_FunctionPointer, CeErrorKind_FunctionPointer,
CeErrorKind_Intrinsic CeErrorKind_Intrinsic
@ -83,6 +84,7 @@ enum CeOp : int16
CeOp_FrameAddr_64, CeOp_FrameAddr_64,
CeOp_FrameAddrOfs_32, CeOp_FrameAddrOfs_32,
CeOp_ConstData,
CeOp_ConstDataRef, CeOp_ConstDataRef,
CeOp_Zero, CeOp_Zero,
CEOP_SIZED(Const), CEOP_SIZED(Const),
@ -255,19 +257,39 @@ enum CeFunctionKind
CeFunctionKind_Char32_IsNumber, CeFunctionKind_Char32_IsNumber,
}; };
class CeConstStructFixup
{
public:
enum Kind
{
Kind_None,
Kind_StringPtr,
Kind_StringCharPtr,
};
public:
Kind mKind;
int mValue;
int mOffset;
};
class CeConstStructData class CeConstStructData
{ {
public: public:
Val128 mHash; Val128 mHash;
Array<uint8> mData; Array<uint8> mData;
Array<uint8> mFixedData;
Array<CeConstStructFixup> mFixups;
addr_ce mAddr; addr_ce mAddr;
int mBindExecuteId; int mBindExecuteId;
bool mQueueFixups;
public: public:
CeConstStructData() CeConstStructData()
{ {
mBindExecuteId = -1; mBindExecuteId = -1;
mAddr = 0; mAddr = 0;
mQueueFixups = false;
} }
}; };
@ -336,7 +358,8 @@ public:
enum CeEvalFlags enum CeEvalFlags
{ {
CeEvalFlags_None = 0 CeEvalFlags_None = 0,
CeEvalFlags_Cascade = 1
}; };
enum CeOperandKind enum CeOperandKind
@ -346,7 +369,7 @@ enum CeOperandKind
CeOperandKind_AllocaAddr, CeOperandKind_AllocaAddr,
CeOperandKind_Block, CeOperandKind_Block,
CeOperandKind_Immediate, CeOperandKind_Immediate,
CeOperandKind_ConstAgg, CeOperandKind_ConstStructTableIdx,
CeOperandKind_CallTableIdx CeOperandKind_CallTableIdx
}; };
@ -360,6 +383,7 @@ public:
int mBlockIdx; int mBlockIdx;
int mImmediate; int mImmediate;
int mCallTableIdx; int mCallTableIdx;
int mStructTableIdx;
BeConstant* mConstant; BeConstant* mConstant;
}; };
BeType* mType; BeType* mType;
@ -554,6 +578,14 @@ public:
} }
}; };
class CeAppendAllocInfo
{
public:
BfModule* mModule;
BfIRValue mAllocValue;
BfIRValue mAppendSizeValue;
};
class CeMachine class CeMachine
{ {
public: public:
@ -575,14 +607,17 @@ public:
Dictionary<Val128, addr_ce> mConstDataMap; Dictionary<Val128, addr_ce> mConstDataMap;
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap; Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
HashSet<int> mStaticCtorExecSet; HashSet<int> mStaticCtorExecSet;
CeAppendAllocInfo* mAppendAllocInfo;
BfAstNode* mCurTargetSrc; BfAstNode* mCurTargetSrc;
BfModule* mCurModule; BfModule* mCurModule;
BfType* mCurExpectingType;
public: public:
CeMachine(BfCompiler* compiler); CeMachine(BfCompiler* compiler);
~CeMachine(); ~CeMachine();
BfError* Fail(const StringImpl& error);
BfError* Fail(const CeFrame& curFrame, const StringImpl& error); BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
void Init(); void Init();
@ -592,14 +627,15 @@ public:
addr_ce GetString(int stringId); addr_ce GetString(int stringId);
addr_ce GetConstantData(BeConstant* constant); addr_ce GetConstantData(BeConstant* constant);
BfType* GetBfType(int typeId); BfType* GetBfType(int typeId);
void PrepareConstStructEntry(CeConstStructData& constStructData);
BeContext* GetBeContext(); BeContext* GetBeContext();
BeModule* GetBeModule(); BeModule* GetBeModule();
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo); void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
void RemoveMethod(BfMethodInstance* methodInstance); void RemoveMethod(BfMethodInstance* methodInstance);
int GetConstantSize(BfConstant* constant); bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type);
CeErrorKind WriteConstant(Array<uint8>& arr, BeConstant* constVal); CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
void WriteConstant(uint8* ptr, BfConstant* constant); BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction); void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr); bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
@ -612,7 +648,11 @@ public:
void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func); void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
void QueueMethod(BfModuleMethodInstance moduleMethodInstance); void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName); void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName);
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
void SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue);
void ClearAppendAllocInfo();
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType);
}; };
NS_BF_END NS_BF_END