mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Fixed issues with global var addresses in const arrays
This commit is contained in:
parent
52af512b4f
commit
b30a72719c
13 changed files with 376 additions and 36 deletions
|
@ -680,7 +680,8 @@ void BeIRCodeGen::Read(BeValue*& beValue)
|
|||
globalVariable->mIsTLS = isTLS;
|
||||
globalVariable->mAlign = varType->mAlign;
|
||||
globalVariable->mUnnamedAddr = false;
|
||||
BF_ASSERT(varType->mAlign > 0);
|
||||
if (initializer != NULL)
|
||||
BF_ASSERT(varType->mAlign > 0);
|
||||
|
||||
SetResult(streamId, globalVariable);
|
||||
beValue = globalVariable;
|
||||
|
@ -721,6 +722,19 @@ void BeIRCodeGen::Read(BeValue*& beValue)
|
|||
BE_MEM_END("ParamType_Const_GEP32_2");
|
||||
return;
|
||||
}
|
||||
else if (constType == BfConstType_ExtractValue)
|
||||
{
|
||||
CMD_PARAM(BeConstant*, target);
|
||||
CMD_PARAM(int, idx0);
|
||||
|
||||
auto gepConstant = mBeModule->mAlloc.Alloc<BeExtractValueConstant>();
|
||||
gepConstant->mTarget = target;
|
||||
gepConstant->mIdx0 = idx0;
|
||||
|
||||
beValue = gepConstant;
|
||||
BE_MEM_END("ParamType_Const_ExtractValue");
|
||||
return;
|
||||
}
|
||||
else if (constType == BfConstType_PtrToInt)
|
||||
{
|
||||
CMD_PARAM(BeConstant*, target);
|
||||
|
|
|
@ -2258,9 +2258,9 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a
|
|||
}
|
||||
case BeGEPConstant::TypeId:
|
||||
{
|
||||
auto gepConstant = (BeGEPConstant*)value;
|
||||
auto gepConstant = (BeGEPConstant*)value;
|
||||
|
||||
auto mcVal = GetOperand(gepConstant->mTarget);
|
||||
auto mcVal = GetOperand(gepConstant->mTarget);
|
||||
|
||||
BePointerType* ptrType = (BePointerType*)GetType(mcVal);
|
||||
BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer);
|
||||
|
@ -2297,6 +2297,21 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a
|
|||
return result;
|
||||
}
|
||||
break;
|
||||
case BeExtractValueConstant::TypeId:
|
||||
{
|
||||
// Note: this only handles zero-aggregates
|
||||
auto extractConstant = (BeExtractValueConstant*)value;
|
||||
auto elementType = extractConstant->GetType();
|
||||
|
||||
auto mcVal = GetOperand(extractConstant->mTarget);
|
||||
auto valType = GetType(mcVal);
|
||||
|
||||
BeConstant beConstant;
|
||||
beConstant.mType = elementType;
|
||||
beConstant.mUInt64 = 0;
|
||||
return GetOperand(&beConstant);
|
||||
}
|
||||
break;
|
||||
case BeFunction::TypeId:
|
||||
{
|
||||
auto sym = mCOFFObject->GetSymbol(value);
|
||||
|
@ -9887,7 +9902,7 @@ bool BeMCContext::DoLegalization()
|
|||
}
|
||||
|
||||
if (arg0Type->IsComposite())
|
||||
{
|
||||
{
|
||||
if (arg1.mKind == BeMCOperandKind_Immediate_i64)
|
||||
{
|
||||
// This is just a "zero initializer" marker
|
||||
|
@ -12185,8 +12200,10 @@ void BeMCContext::EmitAggMov(const BeMCOperand& dest, const BeMCOperand& src)
|
|||
BF_ASSERT(src.mKind == BeMCOperandKind_ConstAgg);
|
||||
auto aggConstant = src.mConstant;
|
||||
|
||||
Array<uint8> dataVec;
|
||||
aggConstant->GetData(dataVec);
|
||||
BeConstData constData;
|
||||
aggConstant->GetData(constData);
|
||||
|
||||
Array<uint8>& dataVec = constData.mData;
|
||||
|
||||
int memSize = dataVec.size();
|
||||
int curOfs = 0;
|
||||
|
@ -12254,7 +12271,7 @@ void BeMCContext::EmitAggMov(const BeMCOperand& dest, const BeMCOperand& src)
|
|||
}
|
||||
else
|
||||
{
|
||||
// movabs r11, val32
|
||||
// movabs r11, val64
|
||||
Emit(0x49); Emit(0xBB);
|
||||
mOut.Write((int64)val);
|
||||
}
|
||||
|
@ -12362,6 +12379,30 @@ void BeMCContext::EmitAggMov(const BeMCOperand& dest, const BeMCOperand& src)
|
|||
Emit(0x89 - 1);
|
||||
EmitModRMRel(EncodeRegNum(X64Reg_R11B), rmInfo.mRegA, rmInfo.mRegB, 1, rmInfo.mDisp + curOfs);
|
||||
}
|
||||
|
||||
for (auto constVal : constData.mConsts)
|
||||
{
|
||||
BeMCRelocation reloc;
|
||||
|
||||
// movabs r11, val64
|
||||
Emit(0x49); Emit(0xBB);
|
||||
|
||||
reloc.mKind = BeMCRelocationKind_ADDR64;
|
||||
reloc.mOffset = mOut.GetPos();
|
||||
|
||||
auto operand = GetOperand(constVal.mConstant);
|
||||
|
||||
reloc.mSymTableIdx = operand.mSymbolIdx;
|
||||
mCOFFObject->mTextSect.mRelocs.push_back(reloc);
|
||||
mTextRelocs.push_back((int)mCOFFObject->mTextSect.mRelocs.size() - 1);
|
||||
|
||||
mOut.Write((int64)0);
|
||||
|
||||
// mov <dest+curOfs>, R11
|
||||
EmitREX(BeMCOperand::FromReg(X64Reg_R11), dest, true);
|
||||
Emit(0x89);
|
||||
EmitModRMRel(EncodeRegNum(X64Reg_R11), rmInfo.mRegA, rmInfo.mRegB, 1, rmInfo.mDisp + constVal.mIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void BeMCContext::DoCodeEmission()
|
||||
|
@ -13166,6 +13207,11 @@ void BeMCContext::DoCodeEmission()
|
|||
{
|
||||
if (inst->mArg1.mKind == BeMCOperandKind_ConstAgg)
|
||||
{
|
||||
if (mDebugging)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
EmitAggMov(inst->mArg0, inst->mArg1);
|
||||
break;
|
||||
}
|
||||
|
@ -15487,7 +15533,7 @@ void BeMCContext::Generate(BeFunction* function)
|
|||
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
||||
|
||||
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
||||
//mDebugging = (function->mName == "?Main@Program@bf@@SAXPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z");
|
||||
mDebugging = (function->mName == "?Hey@Blurg@bf@@SAXXZ");
|
||||
// || (function->mName == "?__BfStaticCtor@roboto_font@Drawing@ClassicUO_assistant@bf@@SAXXZ")
|
||||
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
|
||||
// ;
|
||||
|
|
|
@ -445,25 +445,25 @@ BeType* BeConstant::GetType()
|
|||
return mType;
|
||||
}
|
||||
|
||||
void BeConstant::GetData(Array<uint8>& data)
|
||||
void BeConstant::GetData(BeConstData& data)
|
||||
{
|
||||
auto type = GetType();
|
||||
while ((((int)data.size()) % type->mAlign) != 0)
|
||||
data.push_back(0);
|
||||
while ((((int)data.mData.size()) % type->mAlign) != 0)
|
||||
data.mData.push_back(0);
|
||||
|
||||
if (type->IsComposite())
|
||||
{
|
||||
for (int i = 0; i < type->mSize; i++)
|
||||
data.push_back(0); // Aggregate
|
||||
data.mData.push_back(0); // Aggregate
|
||||
}
|
||||
else if (type->mTypeCode == BeTypeCode_Float)
|
||||
{
|
||||
float f = mDouble;
|
||||
data.Insert(data.mSize, (uint8*)&f, sizeof(float));
|
||||
data.mData.Insert(data.mData.mSize, (uint8*)&f, sizeof(float));
|
||||
}
|
||||
else
|
||||
{
|
||||
data.Insert(data.mSize, &mUInt8, type->mSize);
|
||||
data.mData.Insert(data.mData.mSize, &mUInt8, type->mSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ void BeConstant::HashContent(BeHashContext& hashCtx)
|
|||
BF_FATAL("NotImpl");
|
||||
}
|
||||
|
||||
void BeStructConstant::GetData(Array<uint8>& data)
|
||||
void BeStructConstant::GetData(BeConstData& data)
|
||||
{
|
||||
for (auto val : mMemberValues)
|
||||
val->GetData(data);
|
||||
|
@ -519,6 +519,27 @@ BeType* BeGEPConstant::GetType()
|
|||
}
|
||||
}
|
||||
|
||||
BeType* BeExtractValueConstant::GetType()
|
||||
{
|
||||
BeType* type = mTarget->GetType();
|
||||
if (type->mTypeCode == BeTypeCode_SizedArray)
|
||||
{
|
||||
BeSizedArrayType* arrayType = (BeSizedArrayType*)type;
|
||||
BF_ASSERT(arrayType->mTypeCode == BeTypeCode_SizedArray);
|
||||
return arrayType->mContext->GetPointerTo(arrayType->mElementType);
|
||||
}
|
||||
/*else if (ptrType->mElementType->IsPointer())
|
||||
{
|
||||
return ptrType->mElementType;
|
||||
}*/
|
||||
else
|
||||
{
|
||||
BeStructType* structType = (BeStructType*)type;
|
||||
BF_ASSERT(structType->mTypeCode == BeTypeCode_Struct);
|
||||
return structType->mContext->GetPointerTo(structType->mMembers[mIdx0].mType);
|
||||
}
|
||||
}
|
||||
|
||||
BeType* BeGlobalVariable::GetType()
|
||||
{
|
||||
//if (mIsConstant)
|
||||
|
@ -1240,6 +1261,14 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo
|
|||
return;
|
||||
}
|
||||
|
||||
if (auto constantExtract = BeValueDynCast<BeExtractValueConstant>(value))
|
||||
{
|
||||
str += "ConstExtract ";
|
||||
ToString(str, constantExtract->mTarget);
|
||||
str += StrFormat(" %d", constantExtract->mIdx0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto arg = BeValueDynCast<BeArgument>(value))
|
||||
{
|
||||
auto activeFunction = arg->mModule->mActiveFunction;
|
||||
|
@ -1313,6 +1342,15 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo
|
|||
return;
|
||||
}
|
||||
|
||||
if (auto constant = BeValueDynCast<BeExtractValueConstant>(value))
|
||||
{
|
||||
ToString(str, constant->GetType());
|
||||
str += " extract (";
|
||||
ToString(str, constant->mTarget);
|
||||
str += StrFormat(", %d)", constant->mIdx0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto constant = BeValueDynCast<BeStructConstant>(value))
|
||||
{
|
||||
ToString(str, constant->GetType());
|
||||
|
|
|
@ -271,6 +271,20 @@ class BeDbgLoc;
|
|||
class BeMDNode;
|
||||
class BeGlobalVariable;
|
||||
|
||||
class BeConstant;
|
||||
|
||||
struct BeConstData
|
||||
{
|
||||
struct ConstantEntry
|
||||
{
|
||||
int mIdx;
|
||||
BeConstant* mConstant;
|
||||
};
|
||||
|
||||
Array<uint8> mData;
|
||||
Array<ConstantEntry> mConsts;
|
||||
};
|
||||
|
||||
class BeConstant : public BeValue
|
||||
{
|
||||
public:
|
||||
|
@ -304,7 +318,7 @@ public:
|
|||
}
|
||||
|
||||
virtual BeType* GetType();
|
||||
virtual void GetData(Array<uint8>& data);
|
||||
virtual void GetData(BeConstData& data);
|
||||
virtual void HashContent(BeHashContext& hashCtx) override;
|
||||
};
|
||||
|
||||
|
@ -319,6 +333,11 @@ public:
|
|||
mType->HashReference(hashCtx);
|
||||
mTarget->HashReference(hashCtx);
|
||||
}
|
||||
|
||||
virtual void GetData(BeConstData& data) override
|
||||
{
|
||||
mTarget->GetData(data);
|
||||
}
|
||||
};
|
||||
|
||||
class BeGEPConstant : public BeConstant
|
||||
|
@ -339,6 +358,22 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class BeExtractValueConstant : public BeConstant
|
||||
{
|
||||
public:
|
||||
BE_VALUE_TYPE(BeExtractValueConstant, BeConstant);
|
||||
int mIdx0;
|
||||
|
||||
virtual BeType* GetType();
|
||||
|
||||
virtual void HashContent(BeHashContext& hashCtx) override
|
||||
{
|
||||
hashCtx.Mixin(TypeId);
|
||||
mTarget->HashReference(hashCtx);
|
||||
hashCtx.Mixin(mIdx0);
|
||||
}
|
||||
};
|
||||
|
||||
class BeStructConstant : public BeConstant
|
||||
{
|
||||
public:
|
||||
|
@ -346,7 +381,7 @@ public:
|
|||
|
||||
SizedArray<BeConstant*, 4> mMemberValues;
|
||||
|
||||
virtual void GetData(Array<uint8>& data) override;
|
||||
virtual void GetData(BeConstData& data) override;
|
||||
|
||||
virtual void HashContent(BeHashContext& hashCtx) override
|
||||
{
|
||||
|
@ -399,6 +434,12 @@ public:
|
|||
hashCtx.Mixin(mAlign);
|
||||
hashCtx.Mixin(mUnnamedAddr);
|
||||
}
|
||||
|
||||
virtual void GetData(BeConstData& data) override
|
||||
{
|
||||
data.mConsts.Add({ (int)data.mData.size(), this });
|
||||
data.mData.Insert(data.mData.size(), (uint8)0, 8);
|
||||
}
|
||||
};
|
||||
|
||||
class BeFunctionParam
|
||||
|
@ -679,7 +720,7 @@ public:
|
|||
hashCtx.Mixin(TypeId);
|
||||
mValue->HashReference(hashCtx);
|
||||
mToType->HashReference(hashCtx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class BeNegInst : public BeInst
|
||||
|
|
|
@ -5911,7 +5911,7 @@ void BfCompiler::CompileReified()
|
|||
|
||||
auto typeOptions = scratchModule->GetTypeOptions(typeDef);
|
||||
if (typeOptions != NULL)
|
||||
typeOptions->Apply(isAlwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
|
||||
isAlwaysInclude = typeOptions->Apply(isAlwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
|
||||
|
||||
if (typeDef->mProject->IsTestProject())
|
||||
{
|
||||
|
|
|
@ -17660,9 +17660,30 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
|||
return;
|
||||
}
|
||||
|
||||
if (mResult.mValue.IsConst())
|
||||
{
|
||||
auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
|
||||
bool isNull = constant->mTypeCode == BfTypeCode_NullPtr;
|
||||
|
||||
if (constant->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
auto constExtract = (BfConstantExtractValue*)constant;
|
||||
auto targetConst = mModule->mBfIRBuilder->GetConstantById(constExtract->mTarget);
|
||||
if (targetConst->mConstType == BfConstType_AggZero)
|
||||
isNull = true;
|
||||
}
|
||||
|
||||
if (isNull)
|
||||
{
|
||||
mModule->Warn(0, "Cannot dereference a null pointer", unaryOpExpr);
|
||||
mResult = mModule->GetDefaultTypedValue(mResult.mType, false, BfDefaultValueKind_Addr);
|
||||
mResult = mModule->LoadValue(mResult);
|
||||
}
|
||||
}
|
||||
|
||||
auto derefTarget = mModule->LoadValue(mResult);
|
||||
|
||||
BfPointerType* pointerType = (BfPointerType*)derefTarget.mType;
|
||||
BfPointerType* pointerType = (BfPointerType*)derefTarget.mType;
|
||||
auto resolvedType = mModule->ResolveType(pointerType->mElementType);
|
||||
if (resolvedType == NULL)
|
||||
{
|
||||
|
|
|
@ -578,6 +578,8 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
{
|
||||
BfConstant* copiedConst = NULL;
|
||||
|
||||
int chunkId = -1;
|
||||
|
||||
if ((fromConst->mConstType == BfConstType_BitCast) || (fromConst->mConstType == BfConstType_BitCastNull))
|
||||
{
|
||||
//HMM- This should never happen? Is that true? We always just store string refs as ints
|
||||
|
@ -595,6 +597,21 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
ptrToInt->mToType = fromConstBitCast->mToType;
|
||||
copiedConst = (BfConstant*)ptrToInt;
|
||||
}
|
||||
else if (fromConst->mConstType == BfConstType_GlobalVar)
|
||||
{
|
||||
auto fromGlobalVar = (BfGlobalVar*)fromConst;
|
||||
auto constGV = mTempAlloc.Alloc<BfGlobalVar>();
|
||||
chunkId = mTempAlloc.GetChunkedId(constGV);
|
||||
constGV->mStreamId = -1;
|
||||
constGV->mConstType = BfConstType_GlobalVar;
|
||||
constGV->mType = fromGlobalVar->mType;
|
||||
constGV->mIsConst = fromGlobalVar->mIsConst;
|
||||
constGV->mLinkageType = fromGlobalVar->mLinkageType;
|
||||
constGV->mInitializer = fromGlobalVar->mInitializer;
|
||||
constGV->mName = AllocStr(fromGlobalVar->mName);
|
||||
constGV->mIsTLS = fromGlobalVar->mIsTLS;
|
||||
copiedConst = (BfConstant*)constGV;
|
||||
}
|
||||
else if (fromConst->mConstType == BfConstType_GEP32_2)
|
||||
{
|
||||
auto fromConstGEP = (BfConstantGEP32_2*)fromConst;
|
||||
|
@ -603,8 +620,21 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
auto constGEP = mTempAlloc.Alloc<BfConstantGEP32_2>();
|
||||
constGEP->mConstType = BfConstType_GEP32_2;
|
||||
constGEP->mTarget = copiedTarget.mId;
|
||||
constGEP->mIdx0 = fromConstGEP->mIdx0;
|
||||
constGEP->mIdx1 = fromConstGEP->mIdx1;
|
||||
copiedConst = (BfConstant*)constGEP;
|
||||
}
|
||||
else if (fromConst->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
auto fromConstGEP = (BfConstantExtractValue*)fromConst;
|
||||
auto fromTarget = fromHolder->GetConstantById(fromConstGEP->mTarget);
|
||||
auto copiedTarget = CreateConst(fromTarget, fromHolder);
|
||||
auto constGEP = mTempAlloc.Alloc<BfConstantExtractValue>();
|
||||
constGEP->mConstType = BfConstType_ExtractValue;
|
||||
constGEP->mTarget = copiedTarget.mId;
|
||||
constGEP->mIdx0 = fromConstGEP->mIdx0;
|
||||
copiedConst = (BfConstant*)constGEP;
|
||||
}
|
||||
else if (fromConst->mConstType == BfConstType_TypeOf)
|
||||
{
|
||||
auto typeOf = (BfTypeOf_Const*)fromConst;
|
||||
|
@ -647,7 +677,10 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
|
||||
BfIRValue retVal;
|
||||
retVal.mFlags = BfIRValueFlags_Const;
|
||||
retVal.mId = mTempAlloc.GetChunkedId(copiedConst);
|
||||
if (chunkId == -1)
|
||||
chunkId = mTempAlloc.GetChunkedId(copiedConst);
|
||||
retVal.mId = chunkId;
|
||||
BF_ASSERT(retVal.mId >= 0);
|
||||
#ifdef CHECK_CONSTHOLDER
|
||||
retVal.mHolder = this;
|
||||
#endif
|
||||
|
@ -1243,6 +1276,12 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
|||
BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
|
||||
return ToString(targetConst) + StrFormat(" Gep32 %d,%d", gepConst->mIdx0, gepConst->mIdx1);
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_ExtractValue)
|
||||
{
|
||||
auto gepConst = (BfConstantExtractValue*)constant;
|
||||
BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
|
||||
return ToString(targetConst) + StrFormat(" ExtractValue %d", gepConst->mIdx0);
|
||||
}
|
||||
else if (constant->mConstType == BfConstType_PtrToInt)
|
||||
{
|
||||
auto ptrToIntConst = (BfConstantPtrToInt*)constant;
|
||||
|
@ -1838,6 +1877,14 @@ void BfIRBuilder::Write(const BfIRValue& irValue)
|
|||
Write(gepConst->mIdx1);
|
||||
}
|
||||
break;
|
||||
case (int)BfConstType_ExtractValue:
|
||||
{
|
||||
auto gepConst = (BfConstantExtractValue*)constant;
|
||||
BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
|
||||
Write(targetConst);
|
||||
Write(gepConst->mIdx0);
|
||||
}
|
||||
break;
|
||||
case (int)BfConstType_PtrToInt:
|
||||
{
|
||||
auto ptrToIntConst = (BfConstantPtrToInt*)constant;
|
||||
|
@ -3964,7 +4011,7 @@ BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, int idx0)
|
|||
BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, int idx0, int idx1)
|
||||
{
|
||||
if (val.IsConst())
|
||||
{
|
||||
{
|
||||
auto constGEP = mTempAlloc.Alloc<BfConstantGEP32_2>();
|
||||
constGEP->mConstType = BfConstType_GEP32_2;
|
||||
constGEP->mTarget = val.mId;
|
||||
|
@ -4024,6 +4071,20 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx)
|
|||
auto arrayConstant = (BfConstantArray*)aggConstant;
|
||||
return arrayConstant->mValues[idx];
|
||||
}
|
||||
|
||||
auto constGEP = mTempAlloc.Alloc<BfConstantExtractValue>();
|
||||
constGEP->mConstType = BfConstType_ExtractValue;
|
||||
constGEP->mTarget = val.mId;
|
||||
constGEP->mIdx0 = idx;
|
||||
|
||||
BfIRValue retVal;
|
||||
retVal.mFlags = BfIRValueFlags_Const;
|
||||
retVal.mId = mTempAlloc.GetChunkedId(constGEP);
|
||||
|
||||
#ifdef CHECK_CONSTHOLDER
|
||||
retVal.mHolder = this;
|
||||
#endif
|
||||
return retVal;
|
||||
}
|
||||
|
||||
BfIRValue retVal = WriteCmd(BfIRCmd_ExtractValue, val, idx);
|
||||
|
@ -4213,7 +4274,7 @@ BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, B
|
|||
auto constGV = mTempAlloc.Alloc<BfGlobalVar>();
|
||||
int chunkId = mTempAlloc.GetChunkedId(constGV);
|
||||
constGV->mStreamId = -1;
|
||||
constGV->mConstType = BfConstType_GlobalVar;
|
||||
constGV->mConstType = BfConstType_GlobalVar;
|
||||
constGV->mType = varType;
|
||||
constGV->mIsConst = isConstant;
|
||||
constGV->mLinkageType = linkageType;
|
||||
|
|
|
@ -134,6 +134,7 @@ enum BfConstType
|
|||
BfConstType_BitCast,
|
||||
BfConstType_BitCastNull,
|
||||
BfConstType_GEP32_2,
|
||||
BfConstType_ExtractValue,
|
||||
BfConstType_PtrToInt,
|
||||
BfConstType_TypeOf,
|
||||
BfConstType_AggZero,
|
||||
|
@ -825,6 +826,13 @@ struct BfConstantGEP32_2
|
|||
int mIdx1;
|
||||
};
|
||||
|
||||
struct BfConstantExtractValue
|
||||
{
|
||||
BfConstType mConstType;
|
||||
int mTarget;
|
||||
int mIdx0;
|
||||
};
|
||||
|
||||
struct BfConstantArray
|
||||
{
|
||||
BfConstType mConstType;
|
||||
|
|
|
@ -709,7 +709,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
|||
CMD_PARAM(int, streamId);
|
||||
if (streamId == -1)
|
||||
{
|
||||
int streamId = mCmdCount++;
|
||||
int streamId = mCmdCount++;
|
||||
|
||||
CMD_PARAM(llvm::Type*, varType);
|
||||
CMD_PARAM(bool, isConstant);
|
||||
|
@ -718,13 +718,17 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
|||
CMD_PARAM(String, name);
|
||||
CMD_PARAM(bool, isTLS);
|
||||
|
||||
auto globalVariable = new llvm::GlobalVariable(
|
||||
*mLLVMModule,
|
||||
varType,
|
||||
isConstant,
|
||||
LLVMMapLinkageType(linkageType),
|
||||
initializer,
|
||||
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
|
||||
llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true);
|
||||
if (globalVariable == NULL)
|
||||
{
|
||||
globalVariable = new llvm::GlobalVariable(
|
||||
*mLLVMModule,
|
||||
varType,
|
||||
isConstant,
|
||||
LLVMMapLinkageType(linkageType),
|
||||
initializer,
|
||||
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
|
||||
}
|
||||
llvmValue = globalVariable;
|
||||
|
||||
SetResult(streamId, globalVariable);
|
||||
|
@ -791,6 +795,15 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
|
|||
llvmValue = llvm::ConstantExpr::getInBoundsGetElementPtr(NULL, target, gepArgs);
|
||||
return;
|
||||
}
|
||||
else if (constType == BfConstType_ExtractValue)
|
||||
{
|
||||
CMD_PARAM(llvm::Constant*, target);
|
||||
CMD_PARAM(int, idx0);
|
||||
unsigned int gepArgs[] = {
|
||||
(unsigned int)idx0 };
|
||||
llvmValue = llvm::ConstantExpr::getExtractValue(target, gepArgs);
|
||||
return;
|
||||
}
|
||||
else if (constType == BfConstType_PtrToInt)
|
||||
{
|
||||
CMD_PARAM(llvm::Constant*, target);
|
||||
|
|
|
@ -5388,6 +5388,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
baseTypeId = typeInstance->mBaseType->mTypeId;
|
||||
}
|
||||
|
||||
BfTypeOptions* typeOptions = NULL;
|
||||
if (typeInstance->mTypeOptionsIdx >= 0)
|
||||
typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
|
||||
|
||||
SizedArray<BfIRValue, 16> customAttrs;
|
||||
|
||||
BfTypeInstance* attributeType = mContext->mUnreifiedModule->ResolveTypeDef(mCompiler->mAttributeTypeDef)->ToTypeInstance();
|
||||
|
@ -5716,7 +5720,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
if ((!fieldDef->mIsStatic) && ((fieldReflectKind & ReflectKind_NonStaticFields) != 0))
|
||||
includeField = true;
|
||||
if ((fieldDef->mIsStatic) && ((fieldReflectKind & ReflectKind_StaticFields) != 0))
|
||||
includeField = true;
|
||||
includeField = true;
|
||||
|
||||
if ((!fieldDef->mIsStatic) && (typeOptions != NULL))
|
||||
includeField = typeOptions->Apply(includeField, BfOptionFlags_ReflectNonStaticFields);
|
||||
if ((fieldDef->mIsStatic) && (typeOptions != NULL))
|
||||
includeField = typeOptions->Apply(includeField, BfOptionFlags_ReflectStaticFields);
|
||||
|
||||
includeField |= forceReflectFields;
|
||||
|
||||
if (!includeField)
|
||||
|
@ -6031,7 +6041,20 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
includeMethod = true;
|
||||
if ((methodDef->mIsStatic) && ((methodReflectKind & ReflectKind_StaticMethods) != 0))
|
||||
includeMethod = true;
|
||||
|
||||
|
||||
if (methodDef->mMethodType == BfMethodType_Ctor)
|
||||
{
|
||||
if (typeOptions != NULL)
|
||||
includeMethod = typeOptions->Apply(includeMethod, BfOptionFlags_ReflectConstructors);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((!methodDef->mIsStatic) && (typeOptions != NULL))
|
||||
includeMethod = typeOptions->Apply(includeMethod, BfOptionFlags_ReflectNonStaticMethods);
|
||||
if ((methodDef->mIsStatic) && (typeOptions != NULL))
|
||||
includeMethod = typeOptions->Apply(includeMethod, BfOptionFlags_ReflectStaticMethods);
|
||||
}
|
||||
|
||||
if (!includeMethod)
|
||||
continue;
|
||||
|
||||
|
@ -9820,6 +9843,11 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal)
|
|||
return;
|
||||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_GlobalVar)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
auto origConst = irVal;
|
||||
if ((constant->mConstType == BfConstType_BitCast) || (constant->mConstType == BfConstType_BitCastNull))
|
||||
{
|
||||
|
|
|
@ -1604,6 +1604,7 @@ public:
|
|||
void CheckAddFailType();
|
||||
bool PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
||||
BfTypeOptions* GetTypeOptions(BfTypeDef* typeDef);
|
||||
bool CheckTypeOptionMethodFilters(BfMethodDef* methodDef, BfTypeOptions* typeOptions);
|
||||
int GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeInstance* typeInstance, bool checkTypeName);
|
||||
void SetTypeOptions(BfTypeInstance* typeInstance);
|
||||
BfModuleOptions GetModuleOptions();
|
||||
|
|
|
@ -1473,6 +1473,11 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef)
|
|||
return mSystem->GetTypeOptions( matchedIdx);
|
||||
}
|
||||
|
||||
bool BfModule::CheckTypeOptionMethodFilters(BfMethodDef* methodDef, BfTypeOptions * typeOptions)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeInstance* typeInstance, bool checkTypeName)
|
||||
{
|
||||
if (mContext->mSystem->mTypeOptions.size() == 0)
|
||||
|
@ -2512,9 +2517,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
}
|
||||
|
||||
if (typeInstance->mTypeOptionsIdx == -2)
|
||||
{
|
||||
SetTypeOptions(typeInstance);
|
||||
}
|
||||
SetTypeOptions(typeInstance);
|
||||
|
||||
ProcessCustomAttributeData();
|
||||
bool isPacked = false;
|
||||
|
@ -2530,6 +2533,16 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
typeInstance->mIsPacked = isPacked;
|
||||
typeInstance->mIsCRepr = isCRepr;
|
||||
|
||||
if (typeInstance->mTypeOptionsIdx >= 0)
|
||||
{
|
||||
auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
|
||||
if (typeOptions != NULL)
|
||||
{
|
||||
typeInstance->mIncludeAllMethods = typeOptions->Apply(typeInstance->mIncludeAllMethods, BfOptionFlags_ReflectAlwaysIncludeAll);
|
||||
typeInstance->mHasBeenInstantiated = typeOptions->Apply(typeInstance->mHasBeenInstantiated, BfOptionFlags_ReflectAssumeInstantiated);
|
||||
}
|
||||
}
|
||||
|
||||
BfType* unionInnerType = NULL;
|
||||
bool hadDeferredVars = false;
|
||||
int dataPos;
|
||||
|
@ -3681,6 +3694,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
|
||||
auto typeDef = typeInstance->mTypeDef;
|
||||
|
||||
BfTypeOptions* typeOptions = NULL;
|
||||
if (typeInstance->mTypeOptionsIdx >= 0)
|
||||
typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
|
||||
|
||||
// Generate all methods. Pass 0
|
||||
for (auto methodDef : typeDef->mMethods)
|
||||
{
|
||||
|
@ -3980,6 +3997,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
}
|
||||
if (typeInstance->mIncludeAllMethods)
|
||||
implRequired = true;
|
||||
// if ((typeOptions != NULL) && (CheckTypeOptionMethodFilters(typeOptions, methodDef)))
|
||||
// implRequired = true;
|
||||
|
||||
if (typeInstance->IsInterface())
|
||||
declRequired = true;
|
||||
|
|
50
IDEHelper/Tests/src/Globals.bf
Normal file
50
IDEHelper/Tests/src/Globals.bf
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Globals
|
||||
{
|
||||
static int sVal0 = 123;
|
||||
static int sVal1 = 234;
|
||||
static int sVal2 = 345;
|
||||
|
||||
public const String[3][2] cValStrs = .(("A", "B"), ("C", "D"), );
|
||||
public const String[3][2] cValStrs2 = .(.("A", "B"), .("C", "D"), );
|
||||
public static String[3][2] sValStrs = .(("A", "B"), ("C", "D"), );
|
||||
public static String[3][2] sValStrs2 = .(.("A", "B"), .("C", "D"), );
|
||||
|
||||
public const int*[3][2] cValsInt = .((&sVal0, &sVal1), (&sVal2, ), );
|
||||
public static int*[3][2] sValsInt = .((&sVal0, &sVal1), (&sVal2, ), );
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
const bool cEq0 = cValStrs[0][0] == "A";
|
||||
const bool cEq1 = cValStrs[0][1] == "A";
|
||||
Test.Assert(cEq0);
|
||||
Test.Assert(!cEq1);
|
||||
|
||||
Test.Assert(cValStrs[0][0] === "A");
|
||||
Test.Assert(cValStrs[0][1] === "B");
|
||||
Test.Assert(cValStrs[1][0] === "C");
|
||||
Test.Assert(cValStrs[1][1] === "D");
|
||||
|
||||
Test.Assert(cValStrs2[0][0] === "A");
|
||||
Test.Assert(cValStrs2[0][1] === "B");
|
||||
Test.Assert(cValStrs2[1][0] === "C");
|
||||
Test.Assert(cValStrs2[1][1] === "D");
|
||||
|
||||
Test.Assert(sValStrs[0][0] === "A");
|
||||
Test.Assert(sValStrs[0][1] === "B");
|
||||
Test.Assert(sValStrs[1][0] === "C");
|
||||
Test.Assert(sValStrs[1][1] === "D");
|
||||
|
||||
Test.Assert(*(cValsInt[0][0]) == 123);
|
||||
Test.Assert(*(cValsInt[0][1]) == 234);
|
||||
Test.Assert(*(cValsInt[1][0]) == 345);
|
||||
|
||||
const int* iPtr = cValsInt[2][0];
|
||||
Test.Assert(iPtr == null);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue