diff --git a/IDEHelper/Backend/BeCOFFObject.cpp b/IDEHelper/Backend/BeCOFFObject.cpp index 96f46d34..2e48352d 100644 --- a/IDEHelper/Backend/BeCOFFObject.cpp +++ b/IDEHelper/Backend/BeCOFFObject.cpp @@ -1829,12 +1829,16 @@ void BeCOFFObject::InitSect(BeCOFFSection& sect, const StringImpl& name, int cha MarkSectionUsed(sect, makeSectSymbol); } -void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) -{ +void BeCOFFObject::AlignConst(BeCOFFSection& sect, BeConstant* constVal) +{ auto beType = constVal->GetType(); sect.mAlign = BF_MAX(sect.mAlign, beType->mAlign); sect.mData.Align(beType->mAlign); +} +void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) +{ + auto beType = constVal->GetType(); if (auto globalVar = BeValueDynCast(constVal)) { auto sym = GetSymbol(globalVar); @@ -1881,14 +1885,7 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) } else BF_FATAL("Invalid StructConst type"); - } - else if (auto constArr = BeValueDynCast(constVal)) - { - for (auto member : constArr->mMemberValues) - { - WriteConst(sect, member); - } - } + } else if (auto constStr = BeValueDynCast(constVal)) { sect.mData.Write((void*)constStr->mString.c_str(), (int)constStr->mString.length() + 1); @@ -1995,7 +1992,7 @@ void BeCOFFObject::Generate(BeModule* module) sym->mIsStatic = globalVar->mLinkageType == BfIRLinkageType_Internal; sym->mSymKind = BeMCSymbolKind_External; sym->mIdx = (int)mSymbols.size() - 1; - sym->mIsTLS = globalVar->mIsTLS; + sym->mIsTLS = globalVar->mIsTLS; globalVarSyms.push_back(sym); mSymbolMap[globalVar] = sym; @@ -2013,6 +2010,11 @@ void BeCOFFObject::Generate(BeModule* module) BF_ASSERT(globalVar->mAlign != -1); + if (globalVar->mName == "sBfTypeData._J") + { + NOP; + } + if (globalVar->mIsConstant) { auto constVal = BeValueDynCast(globalVar->mInitializer); @@ -2021,9 +2023,9 @@ void BeCOFFObject::Generate(BeModule* module) sym->mSectionNum = mRDataSect.mSectionIdx + 1; mRDataSect.mData.Align(globalVar->mAlign); mRDataSect.mAlign = BF_MAX(mRDataSect.mAlign, globalVar->mAlign); - sym->mValue = mRDataSect.mData.GetSize(); - //mRDataSect.mSizeOverride += globalVar->mType->mSize; + AlignConst(mRDataSect, constVal); + sym->mValue = mRDataSect.mData.GetSize(); WriteConst(mRDataSect, constVal); } else if (globalVar->mIsTLS) diff --git a/IDEHelper/Backend/BeCOFFObject.h b/IDEHelper/Backend/BeCOFFObject.h index 1736992c..78ce5a40 100644 --- a/IDEHelper/Backend/BeCOFFObject.h +++ b/IDEHelper/Backend/BeCOFFObject.h @@ -272,6 +272,7 @@ public: void DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array& emissions, int blockStartPos, int emissionStartIdx, int lineCount); void DbgGenerateModuleInfo(); void InitSect(BeCOFFSection& sect, const StringImpl& name, int characteristics, bool addNow, bool makeSectSymbol); + void AlignConst(BeCOFFSection& sect, BeConstant* constVal); void WriteConst(BeCOFFSection& sect, BeConstant* constVal); void Generate(BeModule* module); diff --git a/IDEHelper/Backend/BeContext.cpp b/IDEHelper/Backend/BeContext.cpp index 0842c431..cbe013c7 100644 --- a/IDEHelper/Backend/BeContext.cpp +++ b/IDEHelper/Backend/BeContext.cpp @@ -108,7 +108,10 @@ void BeContext::SetStructBody(BeStructType* structType, const SizedArrayImplmSize; - structType->mAlign = std::max(structType->mAlign, beType->mAlign); + if (packed) + structType->mAlign = 1; + else + structType->mAlign = std::max(structType->mAlign, beType->mAlign); structType->mMembers.push_back(member); } if (!packed) diff --git a/IDEHelper/Backend/BeContext.h b/IDEHelper/Backend/BeContext.h index 6b82a9d1..8b62fba1 100644 --- a/IDEHelper/Backend/BeContext.h +++ b/IDEHelper/Backend/BeContext.h @@ -131,7 +131,7 @@ public: { BF_ASSERT(mTypeCode < BeTypeCode_Struct); hashCtx.Mixin(mTypeCode); - } + } }; class BeStructMember diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 2a45b004..43e8bb6f 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -634,7 +634,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) globalVariable->mName = name; globalVariable->mIsTLS = isTLS; globalVariable->mAlign = varType->mAlign; - globalVariable->mUnnamedAddr = false; + globalVariable->mUnnamedAddr = false; BF_ASSERT(varType->mAlign > 0); SetResult(streamId, globalVariable); diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 26a4b7e7..37c726d6 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -2540,6 +2540,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (wasMadeAddr) useType = mModule->CreatePointerType(useType); staticValue = CreateGlobalVariable(mModule->mBfIRBuilder->MapType(useType), true, BfIRLinkageType_Internal, staticValue, staticVarName); + GlobalVar_SetAlignment(staticValue, useType->mAlign); } int flags = 0; diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index d8c522ff..9e7e6e97 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -715,6 +715,7 @@ struct BfGlobalVar int mStreamId; BfIRValue mInitializer; bool mIsTLS; + int mAlignment; }; struct BfGlobalVar_TypeInst diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 98a56b90..c408f614 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -3312,7 +3312,7 @@ void BfIRCodeGen::HandleNextCmd() //BF_ASSERT(file != NULL); llvm::DIExpression* diExpr = NULL; auto gve = mDIBuilder->createGlobalVariableExpression((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum, (llvm::DIType*)type, - isLocalToUnit, diExpr, decl); + isLocalToUnit, diExpr, decl); if (val != NULL) { @@ -3320,7 +3320,7 @@ void BfIRCodeGen::HandleNextCmd() { globalVar->addDebugInfo(gve); } - } + } SetResult(curId, diExpr); } diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 9aa758cb..629dc624 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -3153,6 +3153,7 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo initValue, staticVarName, isThreadLocal); + mBfIRBuilder->GlobalVar_SetAlignment(globalVar, fieldType->mAlign); BF_ASSERT(globalVar); mStaticFieldRefs[fieldInstance] = globalVar; @@ -4114,7 +4115,7 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou true, BfIRLinkageType_External, BfIRValue(), - classVDataName); + classVDataName); mClassVDataRefs[typeInstance] = globalVariable; } @@ -4459,7 +4460,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto reflectPointerType = ResolveTypeDef(mCompiler->mReflectPointerType)->ToTypeInstance(); auto pointerTypeData = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectPointerType, BfIRPopulateType_Full), pointerTypeDataParms); typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectPointerType), true, - BfIRLinkageType_External, pointerTypeData, typeDataName); + BfIRLinkageType_External, pointerTypeData, typeDataName); + typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); } else if (type->IsSizedArray()) @@ -4487,6 +4489,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType)); + mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); mTypeDataRefs[typeInstance] = typeDataVar; return typeDataVar; diff --git a/IDEHelper/DbgExprEvaluator.cpp b/IDEHelper/DbgExprEvaluator.cpp index d263f4cb..391456cc 100644 --- a/IDEHelper/DbgExprEvaluator.cpp +++ b/IDEHelper/DbgExprEvaluator.cpp @@ -4628,7 +4628,8 @@ void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) Fail("Expected single index", indexerExpr->mOpenBracket); return; } - DbgTypedValue indexArgument = indexerValues[0]; + DbgTypedValue indexArgument = indexerValues[0]; + indexArgument.mType = indexArgument.mType->RemoveModifiers(); if (!indexArgument.mType->IsInteger()) { mResult = DbgTypedValue(); diff --git a/IDEHelper/Tests/src/Arrays.bf b/IDEHelper/Tests/src/Arrays.bf new file mode 100644 index 00000000..5c12a333 --- /dev/null +++ b/IDEHelper/Tests/src/Arrays.bf @@ -0,0 +1,31 @@ +using System; +namespace Tests +{ + class Arrays + { + struct StructA + { + public int16 mA = 11; + public int16 mB = 22; + public int16 mC = 33; + } + + [Test] + public static void TestPacking() + { + StructA[] arr = scope .[3](.(), ); + + ref StructA sa = ref arr[0]; + Test.Assert(sa.mA == 11); + Test.Assert(sa.mB == 22); + Test.Assert(sa.mC == 33); + +#if BF_64_BIT + /*int a = (int)(void*)&sa - (int)Internal.UnsafeCastToPtr(arr); + int b = typeof(System.Array).InstanceSize; + + Test.Assert((int)(void*)&sa - (int)Internal.UnsafeCastToPtr(arr) == sizeof(System.Array));*/ +#endif + } + } +} diff --git a/IDEHelper/Tests/src/Reflection.bf b/IDEHelper/Tests/src/Reflection.bf index 07bb8590..e3ed1a98 100644 --- a/IDEHelper/Tests/src/Reflection.bf +++ b/IDEHelper/Tests/src/Reflection.bf @@ -97,6 +97,15 @@ namespace Tests public float mD = 4; } + [Test] + static void TestTypes() + { + Type t = typeof(int32); + Test.Assert(t.InstanceSize == 4); + t = typeof(int64); + Test.Assert(t.InstanceSize == 8); + } + [Test] static void TestA() {