From b30a72719c0d26ffad8e18aa95d30c5b3431684f Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 13 Jul 2020 08:51:02 -0700 Subject: [PATCH] Fixed issues with global var addresses in const arrays --- IDEHelper/Backend/BeIRCodeGen.cpp | 16 +++++- IDEHelper/Backend/BeMCContext.cpp | 60 ++++++++++++++++++--- IDEHelper/Backend/BeModule.cpp | 52 +++++++++++++++--- IDEHelper/Backend/BeModule.h | 47 +++++++++++++++-- IDEHelper/Compiler/BfCompiler.cpp | 2 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 23 +++++++- IDEHelper/Compiler/BfIRBuilder.cpp | 67 ++++++++++++++++++++++-- IDEHelper/Compiler/BfIRBuilder.h | 8 +++ IDEHelper/Compiler/BfIRCodeGen.cpp | 29 +++++++--- IDEHelper/Compiler/BfModule.cpp | 32 ++++++++++- IDEHelper/Compiler/BfModule.h | 1 + IDEHelper/Compiler/BfModuleTypeUtils.cpp | 25 +++++++-- IDEHelper/Tests/src/Globals.bf | 50 ++++++++++++++++++ 13 files changed, 376 insertions(+), 36 deletions(-) create mode 100644 IDEHelper/Tests/src/Globals.bf diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 6b553faa..28063e56 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -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(); + gepConstant->mTarget = target; + gepConstant->mIdx0 = idx0; + + beValue = gepConstant; + BE_MEM_END("ParamType_Const_ExtractValue"); + return; + } else if (constType == BfConstType_PtrToInt) { CMD_PARAM(BeConstant*, target); diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index 389645e2..0e346863 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -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 dataVec; - aggConstant->GetData(dataVec); + BeConstData constData; + aggConstant->GetData(constData); + + Array& 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 , 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") // ; diff --git a/IDEHelper/Backend/BeModule.cpp b/IDEHelper/Backend/BeModule.cpp index a6810d9a..00ece208 100644 --- a/IDEHelper/Backend/BeModule.cpp +++ b/IDEHelper/Backend/BeModule.cpp @@ -445,25 +445,25 @@ BeType* BeConstant::GetType() return mType; } -void BeConstant::GetData(Array& 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& 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(value)) + { + str += "ConstExtract "; + ToString(str, constantExtract->mTarget); + str += StrFormat(" %d", constantExtract->mIdx0); + return; + } + if (auto arg = BeValueDynCast(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(value)) + { + ToString(str, constant->GetType()); + str += " extract ("; + ToString(str, constant->mTarget); + str += StrFormat(", %d)", constant->mIdx0); + return; + } + if (auto constant = BeValueDynCast(value)) { ToString(str, constant->GetType()); diff --git a/IDEHelper/Backend/BeModule.h b/IDEHelper/Backend/BeModule.h index 20781e2c..a30784d9 100644 --- a/IDEHelper/Backend/BeModule.h +++ b/IDEHelper/Backend/BeModule.h @@ -271,6 +271,20 @@ class BeDbgLoc; class BeMDNode; class BeGlobalVariable; +class BeConstant; + +struct BeConstData +{ + struct ConstantEntry + { + int mIdx; + BeConstant* mConstant; + }; + + Array mData; + Array mConsts; +}; + class BeConstant : public BeValue { public: @@ -304,7 +318,7 @@ public: } virtual BeType* GetType(); - virtual void GetData(Array& 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 mMemberValues; - virtual void GetData(Array& 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 diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index bfdc4b91..ef52e9ea 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -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()) { diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index ac8b5171..b1006517 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -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) { diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index b8124032..bbfc2d8a 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -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(); + 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(); 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(); + 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(); 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(); + 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(); 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; diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index b1eab50e..a64378e0 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -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; diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index ce3764d2..8fcf3fef 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -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); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 642ff373..2691771e 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5388,6 +5388,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin baseTypeId = typeInstance->mBaseType->mTypeId; } + BfTypeOptions* typeOptions = NULL; + if (typeInstance->mTypeOptionsIdx >= 0) + typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx); + SizedArray customAttrs; BfTypeInstance* attributeType = mContext->mUnreifiedModule->ResolveTypeDef(mCompiler->mAttributeTypeDef)->ToTypeInstance(); @@ -5716,7 +5720,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& 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& 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)) { diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 9c35af15..a2a50014 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -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(); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index daba7bcd..1704d2b0 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -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; diff --git a/IDEHelper/Tests/src/Globals.bf b/IDEHelper/Tests/src/Globals.bf new file mode 100644 index 00000000..02c644f1 --- /dev/null +++ b/IDEHelper/Tests/src/Globals.bf @@ -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); + } + } +}