diff --git a/BeefySysLib/util/Heap.cpp b/BeefySysLib/util/Heap.cpp index d6e8e306..1150eca6 100644 --- a/BeefySysLib/util/Heap.cpp +++ b/BeefySysLib/util/Heap.cpp @@ -231,6 +231,9 @@ ContiguousHeap::AllocRef ContiguousHeap::Alloc(int size) blockList->PushBack(CH_ABS_TO_REL(block)); mFreeList.Add(CH_ABS_TO_REL(block)); + + if (mFreeIdx >= mFreeList.mSize) + mFreeIdx = 0; } } diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 59b8604a..b3588bbd 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -790,29 +790,47 @@ void BeIRCodeGen::Read(BeValue*& beValue) BE_MEM_END("ParamType_Const_AggZero"); return; } - else if (constType == BfConstType_Array) + else if (constType == BfConstType_Agg) { CMD_PARAM(BeType*, type); CMD_PARAM(CmdParamVec, values); - auto arrayType = (BeSizedArrayType*)type; - int fillCount = (int)(arrayType->mLength - values.size()); - if (fillCount > 0) + if (type->IsSizedArray()) { - auto lastValue = values.back(); - for (int i = 0; i < fillCount; i++) - values.push_back(lastValue); + 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); + } + } + else + { + BF_ASSERT(type->IsStruct()); } auto constStruct = mBeModule->mOwnedValues.Alloc(); - constStruct->mType = type; - for (auto val : values) + constStruct->mType = type; + for (int i = 0; i < (int)values.size(); i++) { + auto val = values[i]; BeConstant* constant = BeValueDynCast(val); constStruct->mMemberValues.push_back(constant); #ifdef _DEBUG - auto memberType = constant->GetType(); - BF_ASSERT(memberType == arrayType->mElementType); + if (type->IsSizedArray()) + { + auto arrayType = (BeSizedArrayType*)type; + auto memberType = constant->GetType(); + BF_ASSERT(memberType == arrayType->mElementType); + } + else + { + auto structType = (BeStructType*)type; + auto memberType = constant->GetType(); + BF_ASSERT(memberType == structType->mMembers[i].mType); + } #endif } beValue = constStruct; @@ -1140,22 +1158,46 @@ void BeIRCodeGen::HandleNextCmd() SetResult(curId, mBeContext->CreateVectorType(elementType, length)); } break; - case BfIRCmd_CreateConstStruct: + case BfIRCmd_CreateConstAgg: { CMD_PARAM(BeType*, type); - CMD_PARAM(CmdParamVec, values) - auto constStruct = mBeModule->mOwnedValues.Alloc(); + CMD_PARAM(CmdParamVec, values); + + auto constStruct = mBeModule->mOwnedValues.Alloc(); 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()); - for (int i = 0; i < (int)values.size(); i++) + BF_ASSERT(((BeStructType*)type)->mMembers.size() == values.size()); + for (int i = 0; i < (int)values.size(); i++) + { + auto val = values[i]; + BF_ASSERT(mBeContext->AreTypesEqual(((BeStructType*)type)->mMembers[i].mType, val->GetType())); + constStruct->mMemberValues.push_back(BeValueDynCast(val)); + } + } + else { - auto val = values[i]; - BF_ASSERT(mBeContext->AreTypesEqual(((BeStructType*)type)->mMembers[i].mType, val->GetType())); - constStruct->mMemberValues.push_back(BeValueDynCast(val)); + 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(val)); + } } SetResult(curId, constStruct); } @@ -1167,19 +1209,7 @@ void BeIRCodeGen::HandleNextCmd() beConst->mType = type; SetResult(curId, beConst); } - break; - case BfIRCmd_CreateConstArray: - { - CMD_PARAM(BeType*, type); - CMD_PARAM(CmdParamVec, values); - - auto constStruct = mBeModule->mOwnedValues.Alloc(); - constStruct->mType = type; - for (auto val : values) - constStruct->mMemberValues.push_back(BeValueDynCast(val)); - SetResult(curId, constStruct); - } - break; + break; case BfIRCmd_CreateConstString: { CMD_PARAM(String, str); diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index 7dace457..f95a222d 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -2864,6 +2864,39 @@ BeMCOperand BeMCContext::CreateLoad(const BeMCOperand& mcTarget) return result; } +static bool NeedsDecompose(BeConstant* constant) +{ + if (auto arrayConst = BeValueDynCast(constant)) + { + for (auto& val : arrayConst->mMemberValues) + { + if (NeedsDecompose(val)) + return true; + } + return false; + } + + if (auto globalVar = BeValueDynCast(constant)) + { + return true; + } + else if (auto castConst = BeValueDynCast(constant)) + { + return true; + } + else if (auto castConst = BeValueDynCast(constant)) + { + if (auto targetConstant = BeValueDynCast(castConst->mValue)) + return NeedsDecompose(targetConstant); + } + else if (auto castConst = BeValueDynCast(constant)) + { + return NeedsDecompose(castConst->mTarget); + } + + return false; +} + void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, const BeMCOperand& ptr) { BeMCOperand mcVal = val; @@ -2871,33 +2904,30 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con if (mcVal.mKind == BeMCOperandKind_ConstAgg) { - bool needsDecompose = false; - - if (auto arrayConst = BeValueDynCast(mcVal.mConstant)) + if (auto aggConst = BeValueDynCast(mcVal.mConstant)) { - for (auto& val : arrayConst->mMemberValues) - { - if (auto globalVar = BeValueDynCast(val)) - { - needsDecompose = true; - } - else if (auto castConst = BeValueDynCast(val)) - { - needsDecompose = true; - } - } - - if (needsDecompose) + if (NeedsDecompose(mcVal.mConstant)) { int offset = 0; - auto arrayType = arrayConst->GetType(); - BEMC_ASSERT(arrayType->IsSizedArray()); - auto sizedArrayType = (BeSizedArrayType*)arrayType; - - for (auto& val : arrayConst->mMemberValues) - { - auto destOperand = AllocVirtualReg(mModule->mContext->GetPointerTo(sizedArrayType->mElementType)); + auto aggType = aggConst->GetType(); + + for (int memberIdx = 0; memberIdx < (int)aggConst->mMemberValues.size(); memberIdx++) + { + 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); vregInfo->mDefOnFirstUse = true; vregInfo->mRelTo = mcPtr; @@ -2905,12 +2935,13 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con vregInfo->mRelOffset = BeMCOperand::FromImmediate(offset); - destOperand.mKind = BeMCOperandKind_VRegLoad; + //destOperand.mKind = BeMCOperandKind_VRegLoad; auto elementVal = GetOperand(val); - AllocInst(instKind, destOperand, elementVal); + //AllocInst(instKind, destOperand, elementVal); + CreateStore(instKind, elementVal, destOperand); - offset += sizedArrayType->mElementType->mSize; + offset += elemType->mSize; } return; } @@ -15742,7 +15773,7 @@ void BeMCContext::Generate(BeFunction* function) mDbgPreferredRegs[32] = X64Reg_R8;*/ //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 == "?Hey@Blurg@bf@@SAXXZ") // ; diff --git a/IDEHelper/Backend/BeModule.cpp b/IDEHelper/Backend/BeModule.cpp index 49099e83..0f6f8dac 100644 --- a/IDEHelper/Backend/BeModule.cpp +++ b/IDEHelper/Backend/BeModule.cpp @@ -3111,9 +3111,7 @@ BeBlock* BeModule::CreateBlock(const StringImpl& name) void BeModule::AddBlock(BeFunction* function, BeBlock* block) { block->mFunction = function; - function->mBlocks.push_back(block); - - //block->mFuncRelId = function->mCurElementId++; + function->mBlocks.push_back(block); } void BeModule::RemoveBlock(BeFunction* function, BeBlock* block) diff --git a/IDEHelper/Backend/BeModule.h b/IDEHelper/Backend/BeModule.h index 605c7f27..ca3a90e2 100644 --- a/IDEHelper/Backend/BeModule.h +++ b/IDEHelper/Backend/BeModule.h @@ -530,8 +530,7 @@ public: Array mBlocks; Array mParams; BeDbgFunction* mDbgFunction; - BeGlobalVariable* mRemapBindVar; - int mCurElementId; + BeGlobalVariable* mRemapBindVar; public: BeFunction() @@ -548,8 +547,7 @@ public: mNoFramePointerElim = false; mIsDLLExport = false; mIsDLLImport = false; - mRemapBindVar = NULL; - mCurElementId = 0; + mRemapBindVar = NULL; } BeFunctionType* GetFuncType() diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index aa1d41fc..a953b335 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -434,6 +434,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mStaticInitAfterAttributeTypeDef = NULL; mStaticInitPriorityAttributeTypeDef = NULL; mStringTypeDef = NULL; + mStringViewTypeDef = NULL; mThreadStaticAttributeTypeDef = NULL; mTypeTypeDef = NULL; mUnboundAttributeTypeDef = NULL; @@ -1359,7 +1360,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) StringT<128> typesVariableName; BfMangler::MangleStaticFieldName(typesVariableName, GetMangleKind(), typeDefType->ToTypeInstance(), "sTypes", typeDefPtrType); 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, typeDataConst, typesVariableName); @@ -1401,7 +1402,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) { auto elemType = bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_Int8)); 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, typeDataConst, "FORCELINK_MODULES"); } @@ -1431,7 +1432,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) stringList.Add(bfModule->mBfIRBuilder->CreateConstNull(stringPtrIRType)); 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); @@ -1459,7 +1460,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } 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); @@ -5378,10 +5379,11 @@ void BfCompiler::PopulateReified() { auto& checkMethodInstanceGroup = typeInst->mMethodInstanceGroups[checkMethodDef->mIdx]; auto checkMethodInstance = checkMethodInstanceGroup.mDefault; - if (checkMethodInstance == NULL) - continue; - if ((checkMethodDef->mIsExtern) && (checkMethodInstance->IsReifiedAndImplemented())) - forceMethod = true; + if (checkMethodInstance != NULL) + { + if ((checkMethodDef->mIsExtern) && (checkMethodInstance->IsReifiedAndImplemented())) + forceMethod = true; + } checkMethodDef = checkMethodDef->mNextWithSameName; } } @@ -6632,6 +6634,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mStaticInitAfterAttributeTypeDef = _GetRequiredType("System.StaticInitAfterAttribute"); mStaticInitPriorityAttributeTypeDef = _GetRequiredType("System.StaticInitPriorityAttribute"); mStringTypeDef = _GetRequiredType("System.String"); + mStringViewTypeDef = _GetRequiredType("System.StringView"); mTestAttributeTypeDef = _GetRequiredType("System.TestAttribute"); mThreadStaticAttributeTypeDef = _GetRequiredType("System.ThreadStaticAttribute"); mTypeTypeDef = _GetRequiredType("System.Type"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index ae5ba550..a6302347 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -349,6 +349,7 @@ public: BfTypeDef* mActionTypeDef; BfTypeDef* mEnumTypeDef; BfTypeDef* mStringTypeDef; + BfTypeDef* mStringViewTypeDef; BfTypeDef* mTypeTypeDef; BfTypeDef* mValueTypeTypeDef; BfTypeDef* mResultTypeDef; diff --git a/IDEHelper/Compiler/BfConstResolver.cpp b/IDEHelper/Compiler/BfConstResolver.cpp index 570fa2da..c4a1ffde 100644 --- a/IDEHelper/Compiler/BfConstResolver.cpp +++ b/IDEHelper/Compiler/BfConstResolver.cpp @@ -59,7 +59,14 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo if (initializer != NULL) { if (auto invocationExpr = BfNodeDynCast(initializer)) - arraySize = (int)invocationExpr->mArguments.size(); + { + if (auto memberRefExpr = BfNodeDynCast(invocationExpr->mTarget)) + { + // Dot-initialized + if (memberRefExpr->mTarget == NULL) + arraySize = (int)invocationExpr->mArguments.size(); + } + } } if (arraySize != -1) @@ -67,6 +74,11 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); 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) { 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); } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index c18e06e0..27c67ce7 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -2628,6 +2628,25 @@ BfAutoComplete* BfExprEvaluator::GetAutoComplete() 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) { 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()) 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; } } @@ -4913,7 +4932,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } 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) val.mKind = BfTypedValueKind_RestrictedTempAddr; return val; @@ -4921,7 +4940,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* }; 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 // This happens for returning Result's with a 'T' value @@ -4982,25 +5001,42 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* return result; } + bool forceBind = false; + if (mModule->mCompiler->mCEMachine != NULL) - { + { if (mModule->mIsConstModule) - { + { mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func); } else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0) { - auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, CeEvalFlags_None); - if (constRet) - return constRet; + 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) + return constRet; + } } } - if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites)) + if (!forceBind) { - // We don't actually submit method calls for unspecialized methods - // - this includes all methods in unspecialized types - return _GetDefaultReturnValue(); + if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites)) + { + // We don't actually submit method calls for unspecialized methods + // - this includes all methods in unspecialized types + return _GetDefaultReturnValue(); + } } if (methodInstance->mVirtualTableIdx != -1) @@ -5137,12 +5173,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } if (mFunctionBindResult != NULL) - { + { mFunctionBindResult->mFunc = funcCallInst; if (irArgs.size() != 0) { 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); else mFunctionBindResult->mTarget = BfTypedValue(irArgs[0], targetType, targetType->IsComposite() ? BfTypedValueKind_Addr : BfTypedValueKind_Value); @@ -5150,7 +5186,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* else { mFunctionBindResult->mTarget = BfTypedValue(); - } + } return BfTypedValue(); } @@ -5214,7 +5250,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if (sret != NULL) { SizedArray sretIRArgs; - int sretIdx = methodInstance->GetStructRetIdx(); + int sretIdx = GetStructRetIdx(methodInstance); int inIdx = 0; for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++) { @@ -5256,7 +5292,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if (methodInstance->mIsIntrinsic) break; - if (argIdx == methodInstance->GetStructRetIdx()) + if (argIdx == GetStructRetIdx(methodInstance)) { mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet); argIdx++; @@ -5303,7 +5339,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* mModule->PopulateType(paramType, BfPopulateType_Data); auto typeInst = paramType->ToTypeInstance(); - if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable())) + if ((typeInst != NULL) && (typeInst->mIsCRepr) && (typeInst->IsSplattable()) && (!IsConstEval())) { // We're splatting } @@ -5346,7 +5382,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* doingThis = false; continue; } - bool isSplatted = methodInstance->GetParamIsSplat(thisIdx); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating); + bool isSplatted = methodInstance->GetParamIsSplat(thisIdx) && (!IsConstEval()); // (resolvedTypeRef->IsSplattable()) && (!methodDef->mIsMutating); if (isSplatted) { BfTypeUtils::SplatIterate(_HandleParamType, paramType); @@ -5380,7 +5416,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* continue; } - if (methodInstance->GetParamIsSplat(paramIdx)) + if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsConstEval())) { BfTypeUtils::SplatIterate(_HandleParamType, paramType); paramIdx++; @@ -5575,6 +5611,7 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& i else if (!checkType->IsValuelessType()) { auto loadedVal = mModule->LoadValue(curValue); + loadedVal = mModule->PrepareConst(loadedVal); irArgs.push_back(loadedVal.mValue); } }; @@ -5595,7 +5632,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir return; bool wantSplat = false; - if ((argVal.mType->IsSplattable()) && (!disableSplat)) + if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsConstEval())) { disableLowering = true; auto argTypeInstance = argVal.mType->ToTypeInstance(); @@ -5610,15 +5647,19 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir else { 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 - } + } else argVal = mModule->MakeAddressable(argVal); - if ((!disableLowering) && (!isIntrinsic)) + if ((!IsConstEval()) && (!disableLowering) && (!isIntrinsic)) { BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; @@ -5678,7 +5719,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; } - if (((argVal.mType->IsComposite()) || (argVal.mType->IsTypedPrimitive()))) + if (((argVal.mType->IsComposite()) || (argVal.mType->IsTypedPrimitive()))) { if ((argVal.IsReadOnly()) || (!argVal.IsAddr())) { @@ -5708,14 +5749,22 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth if (argVal.mType->IsValuelessType()) return; + + auto owner = methodInstance->GetOwner(); - if ((!methodInstance->AllowsThisSplatting()) || (methodDef->mIsMutating)) + bool allowThisSplatting; + if (mModule->mIsConstModule) + allowThisSplatting = owner->IsTypedPrimitive() || owner->IsValuelessType(); + else + allowThisSplatting = methodInstance->AllowsThisSplatting(); + + if ((!allowThisSplatting) || (methodDef->mIsMutating)) { argVal = mModule->MakeAddressable(argVal); irArgs.push_back(argVal.mValue); return; } - + auto thisType = methodInstance->GetThisType(); PushArg(argVal, irArgs, !methodInstance->AllowsThisSplatting(), thisType->IsPointer()); } @@ -6007,7 +6056,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } else { - wantsSplat = methodInstance->GetParamIsSplat(paramIdx); + wantsSplat = methodInstance->GetParamIsSplat(paramIdx) && (!IsConstEval()); if (methodInstance->IsImplicitCapture(paramIdx)) { auto paramType = methodInstance->GetParamType(paramIdx); @@ -6031,14 +6080,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu { if (wantsSplat) { -SplatArgs(lookupVal, irArgs); + SplatArgs(lookupVal, irArgs); } else if (paramType->IsRef()) { - irArgs.push_back(lookupVal.mValue); + irArgs.push_back(lookupVal.mValue); } else - PushArg(lookupVal, irArgs, true); + PushArg(lookupVal, irArgs, true); } } paramIdx++; @@ -6474,7 +6523,7 @@ SplatArgs(lookupVal, irArgs); else { // 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); } @@ -10828,7 +10877,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) hasThis = true; methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes); int thisIdx = 0; - if (methodInstance->GetStructRetIdx() == 0) + if (GetStructRetIdx(methodInstance) == 0) thisIdx = 1; irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance); } @@ -10846,10 +10895,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes); 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, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); + mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_NoAlias); + mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_StructRet); } auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance); @@ -10867,9 +10916,9 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) SizedArray irArgs; 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++; } @@ -10889,7 +10938,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) } int thisIdx = 0; - if (methodInstance->GetStructRetIdx() == 0) + if (GetStructRetIdx(methodInstance) == 0) thisIdx = 1; auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx); BfTypedValue typedVal(fieldPtr, fieldType, true); @@ -10900,16 +10949,16 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (hasThis) 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++; } for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); 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); } @@ -10923,12 +10972,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (mModule->mCompiler->mOptions.mAllowHotSwapping) bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal); auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs); - if (bindMethodInstance->GetStructRetIdx() != -1) - mModule->mBfIRBuilder->Call_AddAttribute(callInst, bindMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); + if (GetStructRetIdx(bindMethodInstance) != -1) + mModule->mBfIRBuilder->Call_AddAttribute(callInst, GetStructRetIdx(bindMethodInstance) + 1, BfIRAttribute_StructRet); auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance); if (destCallingConv != BfIRCallingConv_CDecl) mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv); - if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->GetStructRetIdx() != -1)) + if ((methodInstance->mReturnType->IsValuelessType()) || (GetStructRetIdx(methodInstance) != -1)) { mModule->mBfIRBuilder->CreateRetVoid(); } @@ -11777,15 +11826,15 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam SizedArray newTypes; - if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx(forceStatic) == 0)) + if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 0)) newTypes.push_back(origParamTypes[0]); if (!methodDef->mIsStatic) 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]); int paramStartIdx = 0; - if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx(forceStatic) != -1)) + if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) != -1)) paramStartIdx++; if (!methodDef->mIsStatic) paramStartIdx++; @@ -13143,11 +13192,17 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs else { if (isAppendAlloc) - allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign); + { + allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign); + } else { 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); } @@ -13195,7 +13250,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { mModule->AssertErrorState(); } - else + else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) == 0) { SizedArray irArgs; 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"); BF_ASSERT(markMethod != NULL); @@ -13267,9 +13322,16 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } if (!typeInstance->IsValuelessType()) 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) @@ -13460,6 +13522,8 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa if ((target.mType->IsStruct()) && (!target.IsAddr())) { + if (IsConstEvalEntry()) + return target; target = mModule->MakeAddressable(target); } @@ -13494,7 +13558,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa auto ptrType = mModule->CreatePointerType(primStructType); 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.mKind = BfTypedValueKind_SplatHead; @@ -14865,7 +14929,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m else 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); 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 prevUsedAsStatement(mUsedAsStatement, mUsedAsStatement || isCascade); ResolveArgValues(argValues, resolveArgsFlags); mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArguments, checkedKind); @@ -15875,7 +15944,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp } 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) val.mKind = BfTypedValueKind_TempAddr; return val; @@ -17390,7 +17459,7 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken return mModule->mBfIRBuilder->CreateConstStructZero(mModule->mBfIRBuilder->MapType(checkArrayType)); } 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); diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 6a34e17c..f39710af 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -383,6 +383,9 @@ public: void FinishExpressionResult(); virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode); BfAutoComplete* GetAutoComplete(); + bool IsConstEval(); + bool IsConstEvalEntry(); + int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false); BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken); void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true); BfType* BindGenericType(BfAstNode* node, BfType* bindType); diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index ba076e33..7c664494 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -406,12 +406,12 @@ int BfIRConstHolder::IsZero(BfIRValue value) if (constant->mConstType == BfConstType_AggZero) return 1; - if (constant->mConstType == BfConstType_Array) + if (constant->mConstType == BfConstType_Agg) { - auto constArr = (BfConstantArray*)constant; - for (int i = 0; i < constArr->mValues.mSize; i++) + auto constAgg = (BfConstantAgg*)constant; + for (int i = 0; i < constAgg->mValues.mSize; i++) { - int elemResult = IsZero(constArr->mValues[i]); + int elemResult = IsZero(constAgg->mValues[i]); if (elemResult != 1) return elemResult; } @@ -454,17 +454,17 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) return (constLHS->mUInt64 == constRHS->mUInt64) ? 1 : 0; } - if (constLHS->mConstType == BfConstType_Array) + if (constLHS->mConstType == BfConstType_Agg) { - auto arrayLHS = (BfConstantArray*)constLHS; - auto arrayRHS = (BfConstantArray*)constRHS; + auto aggLHS = (BfConstantAgg*)constLHS; + auto aggRHS = (BfConstantAgg*)constRHS; - if (arrayLHS->mValues.mSize != arrayRHS->mValues.mSize) + if (aggLHS->mValues.mSize != aggRHS->mValues.mSize) 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) return elemResult; } @@ -641,18 +641,18 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f auto aggZero = (BfConstant*)fromConst; 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 copiedVals; - copiedVals.reserve(constArray->mValues.size()); - for (auto fromVal : constArray->mValues) + copiedVals.reserve(constAgg->mValues.size()); + for (auto fromVal : constAgg->mValues) { auto elementConst = fromHolder->GetConstant(fromVal); 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)) { @@ -722,10 +722,10 @@ BfIRValue BfIRConstHolder::CreateConstStructZero(BfIRType aggType) return irValue; } -BfIRValue BfIRConstHolder::CreateConstArray(BfIRType type, const BfSizedArray& values) +BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray& values) { - BfConstantArray* constant = mTempAlloc.Alloc(); - constant->mConstType = BfConstType_Array; + BfConstantAgg* constant = mTempAlloc.Alloc(); + constant->mConstType = BfConstType_Agg; constant->mType = type = type; auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); @@ -1286,17 +1286,17 @@ String BfIRBuilder::ToString(BfIRValue irValue) BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType); } - else if (constant->mConstType == BfConstType_Array) + else if (constant->mConstType == BfConstType_Agg) { - auto constArray = (BfConstantArray*)constant; - String str = ToString(constArray->mType); + auto constAgg = (BfConstantAgg*)constant; + String str = ToString(constAgg->mType); str += "("; - for (int i = 0; i < (int)constArray->mValues.size(); i++) + for (int i = 0; i < (int)constAgg->mValues.size(); i++) { if (i > 0) str += ", "; - str += ToString(constArray->mValues[i]); + str += ToString(constAgg->mValues[i]); } str += ");"; return str; @@ -1915,9 +1915,9 @@ void BfIRBuilder::Write(const BfIRValue& irValue) Write(constant->mIRType); } break; - case (int)BfConstType_Array: + case (int)BfConstType_Agg: { - auto arrayConst = (BfConstantArray*)constant; + auto arrayConst = (BfConstantAgg*)constant; Write(arrayConst->mType); Write(arrayConst->mValues); } @@ -2316,9 +2316,9 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) if (arrayType->mElementType->IsValuelessType()) irType = elementIrType; else if (arrayType->mElementType->IsSizeAligned()) - irType = GetSizedArrayType(MapType(arrayType->mElementType), arrayType->mElementCount); + irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0)); else - irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), arrayType->mSize); + irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), BF_MAX(arrayType->mSize, 0)); if (wantDIData) 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) continue; - if ((constant->mConstType == BfConstType_Array) || + if ((constant->mConstType == BfConstType_Agg) || (constant->mConstType == BfConstType_AggZero) || (constant->mTypeCode == BfTypeCode_NullPtr)) { @@ -3555,6 +3555,7 @@ BfIRType BfIRBuilder::GetPointerTo(BfIRType type) BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length) { + BF_ASSERT(length >= 0); if (mIgnoreWrites) { auto constSizedArrayType = mTempAlloc.Alloc(); @@ -3570,7 +3571,7 @@ BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length) return retType; } else - { + { BfIRType retType = WriteCmd(BfIRCmd_GetSizedArrayType, elementType, length); NEW_CMD_INSERTED_IRTYPE; return retType; @@ -3584,27 +3585,13 @@ BfIRType BfIRBuilder::GetVectorType(BfIRType elementType, int length) return retType; } -BfIRValue BfIRBuilder::CreateConstStruct(BfIRType type, const BfSizedArray& values) +BfIRValue BfIRBuilder::CreateConstAgg_Value(BfIRType type, const BfSizedArray& values) { - BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstStruct, type, values); + BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstAgg, type, values); NEW_CMD_INSERTED_IRVALUE; 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& values) -{ - BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstArray, type, values); - NEW_CMD_INSERTED_IRVALUE; - return retVal; -}*/ - BfIRValue BfIRBuilder::CreateConstString(const StringImpl& str) { BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstString, str); @@ -3620,8 +3607,8 @@ BfIRValue BfIRBuilder::ConstToMemory(BfIRValue constVal) return *value; BfIRType constType; - if (constant->mConstType == BfConstType_Array) - constType = ((BfConstantArray*)constant)->mType; + if (constant->mConstType == BfConstType_Agg) + constType = ((BfConstantAgg*)constant)->mType; else if (constant->mConstType == BfConstType_AggZero) constType = constant->mIRType; else if (constant->mTypeCode == BfTypeCode_NullPtr) @@ -4181,9 +4168,9 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx) auto aggConstant = GetConstant(val); 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]; } @@ -4223,7 +4210,7 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, BfIRValue idx) auto arrConst = GetConstant(val); 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); auto valAddr = CreateInBoundsGEP(arrMemVal, CreateConst(BfTypeCode_IntPtr, 0), idx); @@ -4670,6 +4657,11 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT NEW_CMD_INSERTED_IRVALUE; 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); return retVal; @@ -4955,7 +4947,6 @@ void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm) NEW_CMD_INSERTED_IRBLOCK; if (!mIgnoreWrites) { - BF_ASSERT(!value.IsConst()); BF_ASSERT(!retBlock.IsFake()); mActualInsertBlock = retBlock; } diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 25e5d61b..2bdb3771 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -121,7 +121,7 @@ enum BfConstType BfConstType_IntToPtr, BfConstType_TypeOf, BfConstType_AggZero, - BfConstType_Array, + BfConstType_Agg, BfConstType_ArrayZero, BfConstType_ArrayZero8, BfConstType_Undef, @@ -160,10 +160,9 @@ enum BfIRCmd : uint8 BfIRCmd_GetPointerToType, BfIRCmd_GetSizedArrayType, BfIRCmd_GetVectorType, - - BfIRCmd_CreateConstStruct, + BfIRCmd_CreateConstStructZero, - BfIRCmd_CreateConstArray, + BfIRCmd_CreateConstAgg, BfIRCmd_CreateConstArrayZero, BfIRCmd_CreateConstString, BfIRCmd_ConfigConst, @@ -855,7 +854,7 @@ struct BfConstantExtractValue int mIdx0; }; -struct BfConstantArray +struct BfConstantAgg { BfConstType mConstType; BfIRType mType; @@ -900,7 +899,7 @@ public: BfIRValue CreateConstNull(); BfIRValue CreateConstNull(BfIRType nullType); BfIRValue CreateConstStructZero(BfIRType aggType); - BfIRValue CreateConstArray(BfIRType type, const BfSizedArray& values); + BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray& values); BfIRValue CreateConstArrayZero(BfIRType type, int count); BfIRValue CreateConstArrayZero(int count); BfIRValue CreateTypeOf(BfType* type); @@ -1115,8 +1114,8 @@ public: BfIRType GetPointerTo(BfIRType type); BfIRType GetSizedArrayType(BfIRType elementType, int length); BfIRType GetVectorType(BfIRType elementType, int length); - - BfIRValue CreateConstStruct(BfIRType type, const BfSizedArray& values); + + BfIRValue CreateConstAgg_Value(BfIRType type, const BfSizedArray& values); BfIRValue CreateConstString(const StringImpl& string); BfIRValue ConstToMemory(BfIRValue constVal); BfIRValue GetConfigConst(BfIRConfigConst constType, BfTypeCode typeCode); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index daf6912e..277e788e 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -882,27 +882,44 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry) llvmValue = llvm::ConstantExpr::getPtrToInt(target, llvmToType); 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) { CMD_PARAM(llvm::Type*, type); llvmValue = llvm::ConstantAggregateZero::get(type); return; } - else if (constType == BfConstType_Array) + else if (constType == BfConstType_Agg) { CMD_PARAM(llvm::Type*, type); CMD_PARAM(CmdParamVec, values); - auto arrayType = (llvm::ArrayType*)type; - int fillCount = (int)(arrayType->getNumElements() - values.size()); - if (fillCount > 0) + if (auto arrayType = llvm::dyn_cast(type)) { - auto lastValue = values.back(); - for (int i = 0; i < fillCount; i++) - values.push_back(lastValue); + int fillCount = (int)(arrayType->getNumElements() - values.size()); + if (fillCount > 0) + { + auto lastValue = values.back(); + for (int i = 0; i < fillCount; i++) + values.push_back(lastValue); + } + llvmValue = llvm::ConstantArray::get(arrayType, values); } - - llvmValue = llvm::ConstantArray::get((llvm::ArrayType*)type, values); + else if (auto structType = llvm::dyn_cast(type)) + { + llvmValue = llvm::ConstantStruct::get(structType, values); + } + else + { + Fail("Bad type"); + } + return; } @@ -1616,19 +1633,43 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, llvm::FixedVectorType::get(elementType, length)); } break; - case BfIRCmd_CreateConstStruct: + case BfIRCmd_CreateConstAgg: { CMD_PARAM(llvm::Type*, type); CMD_PARAM(CmdParamVec, values) llvm::SmallVector copyValues; - FixValues((llvm::StructType*)type, values); - for (auto val : values) + + if (auto arrayType = llvm::dyn_cast(type)) { - auto constValue = llvm::dyn_cast(val); - BF_ASSERT(constValue != NULL); - copyValues.push_back(constValue); + for (auto val : values) + { + auto constValue = llvm::dyn_cast(val); + BF_ASSERT(constValue != NULL); + copyValues.push_back(constValue); + } + + 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)); } - SetResult(curId, llvm::ConstantStruct::get((llvm::StructType*)type, copyValues)); + else if (auto structType = llvm::dyn_cast(type)) + { + FixValues(structType, values); + for (auto val : values) + { + auto constValue = llvm::dyn_cast(val); + BF_ASSERT(constValue != NULL); + copyValues.push_back(constValue); + } + SetResult(curId, llvm::ConstantStruct::get(structType, copyValues)); + } + else + Fail("Bad type"); } break; case BfIRCmd_CreateConstStructZero: @@ -1636,14 +1677,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::Type*, type); SetResult(curId, llvm::ConstantAggregateZero::get(type)); } - break; - case BfIRCmd_CreateConstArray: - { - CMD_PARAM(llvm::Type*, type); - CMD_PARAM(CmdParamVec, values); - SetResult(curId, llvm::ConstantArray::get((llvm::ArrayType*)type, values)); - } - break; + break; case BfIRCmd_CreateConstString: { CMD_PARAM(String, str); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 007ba8fb..b94c931c 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1530,7 +1530,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, SizedArray 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; @@ -1558,7 +1558,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, 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); @@ -4823,7 +4823,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy BfIRLinkageType_External, BfIRValue(), classVDataName); 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); mClassVDataExtRefs[mapEntry] = globalVariable; @@ -4966,7 +4966,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin SizedArray 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; if ((typeInstance != NULL) && (!typeInstance->IsTypeAlias())) @@ -5078,7 +5078,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(typeCode, byteType), // mTypeCode 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) { @@ -5096,7 +5096,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; 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, BfIRLinkageType_External, pointerTypeData, typeDataName); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); @@ -5113,7 +5113,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; 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, BfIRLinkageType_External, refTypeData, typeDataName); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); @@ -5130,7 +5130,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; 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, BfIRLinkageType_External, sizedArrayTypeData, typeDataName); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); @@ -5663,7 +5663,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfIRLinkageType_External, BfIRValue(), classVDataName); 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); } @@ -5764,7 +5764,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin // Fields BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef); - BfIRValue emptyValueType = mBfIRBuilder->CreateConstStruct(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray()); + BfIRValue emptyValueType = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray()); auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes) { @@ -5930,7 +5930,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin for (uint8 val : data) dataValues.push_back(GetConstValue8(val)); 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, customAttrConst, typeDataName + StrFormat(".customAttr%d", customAttrIdx)); @@ -6039,7 +6039,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags 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); } @@ -6054,7 +6054,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags 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); } @@ -6132,7 +6132,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(fieldFlags, shortType), // mFlags 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); } @@ -6214,15 +6214,15 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin splatOffsets.Add(GetConstValue(0, intType)); } - BfIRValue splatTypesConst = mBfIRBuilder->CreateConstArray(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[0].mResolvedType), splatTypes); - BfIRValue splatOffsetsConst = mBfIRBuilder->CreateConstArray(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[1].mResolvedType), splatOffsets); + BfIRValue splatTypesConst = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[0].mResolvedType), splatTypes); + BfIRValue splatOffsetsConst = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[1].mResolvedType), splatOffsets); SizedArray splatVals = { emptyValueType, splatTypesConst, 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, fieldSplatData, typeDataName + ".splats"); @@ -6234,7 +6234,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else { 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, fieldDataConst, "fields." + typeDataName); fieldDataPtr = mBfIRBuilder->CreateBitCast(fieldDataArray, fieldDataPtrType); @@ -6409,7 +6409,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue((int32)paramFlags, shortType), 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); } @@ -6417,7 +6417,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (paramVals.size() > 0) { 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, paramDataConst, typeDataName + StrFormat(".params%d", methodIdx)); @@ -6477,7 +6477,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(vDataVal, 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); } @@ -6488,7 +6488,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else { 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, methodDataConst, "methods." + typeDataName); methodDataPtr = mBfIRBuilder->CreateBitCast(methodDataArray, methodDataPtrType); @@ -6517,7 +6517,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin 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); for (int methodIdx = 0; methodIdx < (int)interface.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++) @@ -6535,7 +6535,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } 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, interfaceDataConst, "interfaces." + typeDataName); interfaceDataPtr = mBfIRBuilder->CreateBitCast(interfaceDataArray, interfaceDataPtrType); @@ -6575,7 +6575,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (!methods.IsEmpty()) { 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, methodDataConst, "imethods." + typeDataName); interfaceMethodTable = mBfIRBuilder->CreateBitCast(methodDataArray, voidPtrPtrIRType); @@ -6606,7 +6606,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (customAttrs.size() > 0) { 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, customAttrsConst, "customAttrs." + typeDataName); customAttrDataPtr = mBfIRBuilder->CreateBitCast(customAttrsArray, voidPtrPtrIRType); @@ -6649,7 +6649,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; BfIRType typeInstanceDataType = mBfIRBuilder->MapTypeInst(typeInstanceType->ToTypeInstance(), BfIRPopulateType_Full); - auto typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, typeDataVals); + auto typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, typeDataVals); if (!needsTypeData) { @@ -6666,7 +6666,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; auto reflectUnspecializedGenericType = ResolveTypeDef(mCompiler->mReflectUnspecializedGenericType); typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectUnspecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full); - typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, unspecializedData); + typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, unspecializedData); } else if (typeInstance->IsGenericTypeInstance()) { @@ -6681,7 +6681,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto typeIRType = mBfIRBuilder->MapType(typeIdType); auto typePtrIRType = mBfIRBuilder->GetPointerTo(typeIRType); 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, resolvedTypesConst, "resolvedTypes." + typeDataName); BfIRValue resovledTypesPtr = mBfIRBuilder->CreateBitCast(resolvedTypesArray, typePtrIRType); @@ -6694,7 +6694,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectSpecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full); - typeInstanceData = mBfIRBuilder->CreateConstStruct(typeInstanceDataType, specGenericData); + typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, specGenericData); if (typeInstance->IsArray()) { @@ -6712,7 +6712,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; auto reflectArrayType = ResolveTypeDef(mCompiler->mReflectArrayType); 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& usedStrin vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType); 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); if (mCompiler->mOptions.mObjectHasDebugFlags) @@ -8276,7 +8276,7 @@ BfIRValue BfModule::GetDbgRawAllocData(BfType* type) dataValues.Add(typeDataRef); dataValues.Add(markFuncPtr); 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)); mDbgRawAllocDataRefs.TryAdd(type, allocDataValue); @@ -8874,7 +8874,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance())); - if (mCompiler->mOptions.mObjectHasDebugFlags) + if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule)) { SizedArray llvmArgs; llvmArgs.push_back(vData); @@ -10367,9 +10367,9 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal) return; } - if (constant->mConstType == BfConstType_Array) + if (constant->mConstType == BfConstType_Agg) { - auto constArray = (BfConstantArray*)constant; + auto constArray = (BfConstantAgg*)constant; SizedArray newVals; for (auto val : constArray->mValues) @@ -10379,7 +10379,7 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal) newVals.push_back(newVal); } - irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstArray(constArray->mType, newVals); + irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstAgg(constArray->mType, newVals); return; } @@ -10485,6 +10485,12 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con { 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); } @@ -10501,18 +10507,49 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con } } - if (constant->mConstType == BfConstType_Array) - { - auto elementType = wantType->GetUnderlyingType(); - auto constArray = (BfConstantArray*)constant; + if (constant->mConstType == BfConstType_Agg) + { + auto constArray = (BfConstantAgg*)constant; + + if ((wantType == NULL) && (constArray->mType.mKind == BfIRTypeData::TypeKind_TypeId)) + wantType = mContext->mTypes[constArray->mType.mId]; SizedArray newVals; - for (auto val : constArray->mValues) + if (wantType->IsSizedArray()) { - newVals.push_back(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType)); + auto elementType = wantType->GetUnderlyingType(); + for (auto val : constArray->mValues) + { + 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); + } + + 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->CreateConstArray(mBfIRBuilder->MapType(wantType), newVals); + return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(wantType), newVals); } return mBfIRBuilder->CreateConst(constant, constHolder); @@ -11290,6 +11327,17 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo 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) { if (typedValue.IsSplat()) @@ -11303,6 +11351,7 @@ BfTypedValue BfModule::AggregateSplat(BfTypedValue typedValue, BfIRValue* valueA { if (!typedValue.IsSplat()) return typedValue; + BF_ASSERT(!mIsConstModule); if (typedValue.mType->IsValuelessType()) return typedValue; @@ -11399,6 +11448,8 @@ void BfModule::AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal if (typedValue.mType->IsValuelessType()) return; + BF_ASSERT(!mIsConstModule); + /*static int sCallIdx = 0; if (!mCompiler->mIsResolveOnly) sCallIdx++; @@ -11523,6 +11574,8 @@ BfTypedValue BfModule::RemoveReadOnly(BfTypedValue typedValue) BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, BfType* wantType, bool* isAddr) { + BF_ASSERT(!mIsConstModule); + BfIRValue val; if (typedValue.mValue.IsArg()) { @@ -13510,7 +13563,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli isConstant = (constant->mConstType < BfConstType_GlobalVar) || (constant->mConstType == BfConstType_AggZero) || - (constant->mConstType == BfConstType_Array); + (constant->mConstType == BfConstType_Agg); if (isConstant) { if (localVarDef->mResolvedType->IsComposite()) @@ -13639,7 +13692,7 @@ void BfModule::CreateDIRetVal() { BfType* dbgType = mCurMethodInstance->mReturnType; BfIRValue dbgValue = mCurMethodState->mRetVal.mValue; - if (mCurMethodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) { BF_ASSERT(mCurMethodState->mRetValAddr); dbgType = CreatePointerType(dbgType); @@ -14255,7 +14308,7 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData) void BfModule::CreateReturn(BfIRValue val) { - if (mCurMethodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) { // Store to sret BF_ASSERT(val); @@ -14274,7 +14327,8 @@ void BfModule::CreateReturn(BfIRValue val) { BfTypeCode loweredReturnType = BfTypeCode_None; BfTypeCode loweredReturnType2 = BfTypeCode_None; - mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2); + if (!mIsConstModule) + mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2); if (loweredReturnType != BfTypeCode_None) { @@ -14341,7 +14395,7 @@ void BfModule::EmitDefaultReturn() { if (mCurMethodInstance->mReturnType->IsVoid()) mBfIRBuilder->CreateRetVoid(); - else if (mCurMethodInstance->GetStructRetIdx() == -1) + else if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() == -1)) mBfIRBuilder->CreateRet(GetDefaultValue(mCurMethodInstance->mReturnType)); } @@ -14450,18 +14504,18 @@ void BfModule::CreateDelegateInvokeMethod() if (mCurMethodInstance->mReturnType->IsValueType()) mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full); - if (mCurMethodInstance->GetStructRetIdx() != 0) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != 0)) memberFuncArgs.push_back(BfIRValue()); // Push 'target' int thisIdx = 0; - if (mCurMethodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) { thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; staticFuncArgs.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' mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true); @@ -14500,7 +14554,7 @@ void BfModule::CreateDelegateInvokeMethod() auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr); auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr); nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs); - if (mCurMethodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) mBfIRBuilder->Call_AddAttribute(nonStaticResult, mCurMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet); if (callingConv != BfIRCallingConv_CDecl) mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv); @@ -14518,7 +14572,7 @@ void BfModule::CreateDelegateInvokeMethod() auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr); auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr); 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 mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet); @@ -14535,7 +14589,8 @@ void BfModule::CreateDelegateInvokeMethod() mBfIRBuilder->AddBlock(doneBB); mBfIRBuilder->SetInsertPoint(doneBB); - if ((mCurMethodInstance->mReturnType->IsValuelessType()) || (mCurMethodInstance->GetStructRetIdx() != -1)) + if ((mCurMethodInstance->mReturnType->IsValuelessType()) || + ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1))) { mBfIRBuilder->CreateRetVoid(); } @@ -14544,7 +14599,7 @@ void BfModule::CreateDelegateInvokeMethod() BfIRType loweredIRReturnType; BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; - if (mCurMethodInstance->GetLoweredReturnType(&loweredTypeCode, &loweredTypeCode2)) + if ((!mIsConstModule) && (mCurMethodInstance->GetLoweredReturnType(&loweredTypeCode, &loweredTypeCode2))) loweredIRReturnType = GetIRLoweredType(loweredTypeCode, loweredTypeCode2); else loweredIRReturnType = mBfIRBuilder->MapType(mCurMethodInstance->mReturnType); @@ -14624,7 +14679,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr int argCount = 0; if (!paramType->IsValuelessType()) { - if (methodInst->GetParamIsSplat(paramIdx)) + if ((!mIsConstModule) && (methodInst->GetParamIsSplat(paramIdx))) argCount = paramType->GetSplatCount(); else argCount = 1; @@ -15449,7 +15504,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func 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_StructRet); @@ -15473,8 +15528,8 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func resolvedTypeRef = mCurMethodState->mClosureState->mClosureType; else resolvedTypeRef = methodInstance->GetThisType(); - isSplattable = (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting()); - tryLowering = methodInstance->AllowsThisSplatting(); + isSplattable = (!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting()); + tryLowering = (!mIsConstModule) && (methodInstance->AllowsThisSplatting()); } else { @@ -15482,7 +15537,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func resolvedTypeRef = methodInstance->GetParamType(paramIdx); if (resolvedTypeRef->IsMethodRef()) isSplattable = true; - else if ((resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting())) + else if ((!mIsConstModule) && (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting())) { auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance(); if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr)) @@ -16620,7 +16675,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp int argIdx = 0; - if (argIdx == methodInstance->GetStructRetIdx()) + if ((!mIsConstModule) && (argIdx == methodInstance->GetStructRetIdx())) argIdx++; if (!methodDef->mIsStatic) @@ -16636,12 +16691,12 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp else paramVar->mValue = mBfIRBuilder->GetFakeVal(); - if ((thisType->IsSplattable()) && (methodInstance->AllowsThisSplatting())) + if ((!mIsConstModule) && (thisType->IsSplattable()) && (methodInstance->AllowsThisSplatting())) { if (!thisType->IsTypedPrimitive()) 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; 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++; bool hadParams = false; @@ -16730,7 +16785,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp } else if (resolvedType->IsComposite() && resolvedType->IsSplattable()) { - if (methodInstance->AllowsSplatting()) + if ((!mIsConstModule) && (methodInstance->AllowsSplatting())) { int splatCount = resolvedType->GetSplatCount(); if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs) @@ -16744,7 +16799,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp 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->mParamIdx = paramIdx; paramVar->mIsImplicitParam = methodInstance->IsImplicitCapture(paramIdx); @@ -17291,7 +17346,7 @@ void BfModule::EmitGCMarkMembers() auto baseValue = Cast(NULL, thisValue, methodBaseType, BfCastFlags_Explicit); SizedArray args; - if (moduleMethodInst.mMethodInstance->GetParamIsSplat(-1)) + if ((!mIsConstModule) && (moduleMethodInst.mMethodInstance->GetParamIsSplat(-1))) { BfExprEvaluator exprEvaluator(this); exprEvaluator.SplatArgs(baseValue, args); @@ -17945,7 +18000,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) flags |= llvm::DINode::FlagStaticMember; else { - if ((mCurTypeInstance->IsValuelessType()) || (mCurTypeInstance->IsSplattable())) + if ((mCurTypeInstance->IsValuelessType()) || + ((!mIsConstModule) && (mCurTypeInstance->IsSplattable()))) flags |= llvm::DINode::FlagStaticMember; } flags |= llvm::DINode::FlagPrototyped; @@ -18095,7 +18151,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) if ((isThis) && (thisType->IsValuelessType())) isThis = false; - if (methodInstance->GetStructRetIdx() == argIdx) + if ((!mIsConstModule) && (methodInstance->GetStructRetIdx() == argIdx)) { argIdx++; if (argIdx == irParamCount) @@ -18118,7 +18174,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) 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()) wantsAddr = false; @@ -18259,7 +18316,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) int splatAddrIdx = 0; while (localIdx < (int)methodState.mLocals.size()) { - if (argIdx == methodInstance->GetStructRetIdx()) + if ((!mIsConstModule) && (argIdx == methodInstance->GetStructRetIdx())) argIdx++; int curLocalIdx = localIdx++; @@ -18695,7 +18752,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) { BF_ASSERT(innerType->IsUnspecializedType()); } - else if (methodInstance->GetStructRetIdx() != -1) + else if ((!mIsConstModule) && (methodInstance->GetStructRetIdx() != -1)) { mBfIRBuilder->PopulateType(methodInstance->mReturnType); auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true); @@ -19071,8 +19128,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) { mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType); - if (mCurMethodInstance->GetStructRetIdx() != -1) - { + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) + { auto ptrType = CreatePointerType(mCurMethodInstance->mReturnType); auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false); auto storeInst = mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()), allocaInst); @@ -19264,7 +19321,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) if (mCurMethodState->mIRExitBlock) { - if ((mCurMethodState->mRetVal) && (mCurMethodInstance->GetStructRetIdx() == -1)) + if ((mCurMethodState->mRetVal) && + ((mIsConstModule) || (mCurMethodInstance->GetStructRetIdx() == -1))) { auto loadedVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetVal.mValue); @@ -19303,7 +19361,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) { 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 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 // 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); mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); } @@ -21405,7 +21463,7 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); { BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; - if (!methodDef->mIsMutating) + if ((!mIsConstModule) && (!methodDef->mIsMutating)) thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2); argIdx++; if (loweredTypeCode2 != BfTypeCode_None) @@ -21413,7 +21471,7 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); } } - if (methodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (methodInstance->GetStructRetIdx() != -1)) argIdx++; for (int paramIdx = 0; paramIdx < mCurMethodInstance->mParams.size(); paramIdx++) @@ -21449,7 +21507,8 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); { BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; - checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2); + if (!mIsConstModule) + checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2); argIdx++; if (loweredTypeCode2 != BfTypeCode_None) argIdx++; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index ddf74aa3..211a13b3 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1593,6 +1593,7 @@ public: BfTypedValue RemoveRef(BfTypedValue typedValue); BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue); BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false); + BfTypedValue PrepareConst(BfTypedValue& typedValue); void AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal); BfTypedValue AggregateSplat(BfTypedValue typedValue, BfIRValue* valueArrPtr = NULL); BfTypedValue MakeAddressable(BfTypedValue typedValue); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 29a859ba..08888804 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5328,6 +5328,8 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode) BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2) { + BF_ASSERT(!mIsConstModule); + BF_ASSERT(loweredTypeCode != BfTypeCode_None); if (loweredTypeCode2 == BfTypeCode_None) return mBfIRBuilder->GetPrimitiveType(loweredTypeCode); @@ -9798,7 +9800,7 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targe } BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags, BfCastResultFlags* resultFlags) -{ +{ bool silentFail = ((castFlags & BfCastFlags_SilentFail) != 0); bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0; bool ignoreErrors = mIgnoreErrors || ((castFlags & BfCastFlags_SilentFail) != 0); @@ -10763,11 +10765,40 @@ 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()) { - int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder); - if (stringId >= 0) - return GetStringCharPtr(stringId); + if ((toType->IsPointer()) && (toType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) && (typedVal.mType->IsInstanceOf(mCompiler->mStringTypeDef))) + { + int stringId = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder); + if (stringId >= 0) + 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 spanFieldVals; + spanFieldVals.Add(mBfIRBuilder->CreateConstStructZero(mBfIRBuilder->MapType(svTypeInst->mBaseType->mBaseType))); + spanFieldVals.Add(stringCharPtr); + spanFieldVals.Add(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, entry->mString.mLength)); + + SizedArray svFieldVals; + svFieldVals.Add(mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst->mBaseType), spanFieldVals)); + return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst), svFieldVals); + } + } + } } // Check user-defined operators @@ -11275,6 +11306,15 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf 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 (toType->IsValuelessType()) @@ -11575,11 +11615,11 @@ BfTypedValue BfModule::GetIntCoercible(const BfTypedValue& typedValue) if (typedValue.mValue.IsConst()) { auto constant = mBfIRBuilder->GetConstant(typedValue.mValue); - if (constant->mConstType == BfConstType_Array) + if (constant->mConstType == BfConstType_Agg) { uint64 intVal = 0; - auto constantArray = (BfConstantArray*)constant; + auto constantArray = (BfConstantAgg*)constant; int memberIdx = 0; for (int memberIdx = 0; memberIdx < (int)constantArray->mValues.size(); memberIdx++) { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 0c499d70..429f5f1d 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -1096,7 +1096,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, BfTypeCode loweredReturnTypeCode = BfTypeCode_None; BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None; - if (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2)) + if ((!module->mIsConstModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2))) { auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2); returnType = irReturnType; @@ -1106,7 +1106,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, auto voidType = module->GetPrimitiveType(BfTypeCode_None); returnType = module->mBfIRBuilder->MapType(voidType); } - else if (GetStructRetIdx(forceStatic) != -1) + else if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) != -1)) { auto voidType = module->GetPrimitiveType(BfTypeCode_None); returnType = module->mBfIRBuilder->MapType(voidType); @@ -1125,11 +1125,9 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, { returnType = module->mBfIRBuilder->MapType(mReturnType); } - - for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++) - { + { BfType* checkType = NULL; if (paramIdx == -1) { @@ -1150,7 +1148,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, else { checkType = GetParamType(paramIdx); - } + } /*if (GetParamName(paramIdx) == "this") { @@ -1161,11 +1159,15 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, bool doSplat = false; if (paramIdx == -1) { - if ((checkType->IsSplattable()) && (AllowsThisSplatting())) + if ((!mMethodDef->mIsMutating) && (checkType->IsTypedPrimitive())) + { + checkType = checkType->GetUnderlyingType(); + } + else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsThisSplatting())) { doSplat = true; } - else if ((!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified)) + else if ((!module->mIsConstModule) && (!mMethodDef->mIsMutating) && (mCallingConvention == BfCallingConvention_Unspecified)) checkLowered = true; } else @@ -1174,11 +1176,15 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, { doSplat = true; } - else if ((checkType->IsSplattable()) && (AllowsSplatting())) + else if (checkType->IsTypedPrimitive()) + { + checkType = checkType->GetUnderlyingType(); + } + else if ((!module->mIsConstModule) && (checkType->IsSplattable()) && (AllowsSplatting())) { doSplat = true; } - else + else if (!module->mIsConstModule) checkLowered = true; } @@ -1258,7 +1264,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, paramIdx++; // Skip over the explicit 'this' } - if (GetStructRetIdx(forceStatic) == 1) + if ((!module->mIsConstModule) && (GetStructRetIdx(forceStatic) == 1)) { BF_SWAP(paramTypes[0], paramTypes[1]); } @@ -3082,7 +3088,12 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash if (typedVal) { 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 } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index c38ad295..767c248d 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -528,6 +528,7 @@ public: virtual bool IsObjectOrInterface() { return false; } virtual bool IsString() { return false; } virtual bool IsSizedArray() { return false; } + virtual bool IsUndefSizedArray() { return false; } virtual bool IsUnknownSizedArray() { return false; } virtual bool IsArray() { return false; } virtual bool IsDelegate() { return false; } @@ -2277,6 +2278,7 @@ public: virtual bool NeedsExplicitAlignment() override { return mElementType->NeedsExplicitAlignment(); } virtual bool IsSizedArray() override { return true; } + virtual bool IsUndefSizedArray() override { return mElementCount == -1; } virtual bool IsWrappableType() override { return true; } virtual bool IsValueType() override { return true; } // Is a type of struct diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 24a3a79b..b18ffbcf 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1594,9 +1594,6 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD } } }; - - PopulateType(resolvedType); - AddDependency(resolvedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); localDef->mResolvedType = resolvedType; localDef->mIsReadOnly = isReadOnly; @@ -1656,8 +1653,9 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { BfConstResolver constResolver(this); initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId); - if (!initValue) - initValue = GetDefaultTypedValue(resolvedType); + if (!initValue) + initValue = GetDefaultTypedValue(resolvedType); + } else if (varDecl->mInitializer->IsA()) { @@ -1680,15 +1678,12 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if ((!handledVarInit) && (initValue)) initValue = Cast(varDecl->mInitializer, initValue, resolvedType, BfCastFlags_PreferAddr); - - // Why did we remove this? -// if ((valExprEvaluator.mResultIsTempComposite) && (initValue.IsAddr())) -// { -// BF_ASSERT(initValue.mType->IsComposite()); -// localDef->mAddr = initValue.mValue; -// handledVarInit = true; -// handledVarStore = true; -// } + } + + if ((initValue) && (resolvedType->IsUndefSizedArray())) + { + resolvedType = initValue.mType; + unresolvedType = resolvedType; } } if ((!handledVarInit) && (!isConst)) @@ -1728,10 +1723,15 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD } else { - BF_ASSERT(!localDef->mResolvedType->IsRef()); + BF_ASSERT(!resolvedType->IsRef()); } } + PopulateType(resolvedType); + AddDependency(resolvedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); + + localDef->mResolvedType = resolvedType; + _CheckConst(); if ((initValue.mKind == BfTypedValueKind_TempAddr) && (!initHandled)) @@ -1771,6 +1771,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD initValue = LoadValue(initValue); if (initValue.IsSplat()) { + BF_ASSERT(!mIsConstModule); if (!localDef->mAddr) localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName); AggregateSplatIntoAddr(initValue, localDef->mAddr); @@ -4945,12 +4946,12 @@ void BfModule::Visit(BfReturnStatement* returnStmt) BfType* origType; BfExprEvaluator exprEvaluator(this); bool alreadyWritten = false; - if (mCurMethodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal; if (mCurMethodInstance->mMethodDef->mIsReadOnly) exprEvaluator.mAllowReadOnlyReference = true; auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType); - if (mCurMethodInstance->GetStructRetIdx() != -1) + if ((!mIsConstModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) alreadyWritten = exprEvaluator.mReceivingValue == NULL; MarkScopeLeft(&mCurMethodState->mHeadScope); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 21cbd873..ab08326e 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -12,6 +12,12 @@ extern "C" USING_NS_BF; +enum CeOpInfoFlag +{ + CeOpInfoFlag_None, + CeOpInfoFlag_SizeX, +}; + struct CeOpInfo { const char* mName; @@ -19,6 +25,7 @@ struct CeOpInfo CeOperandInfoKind mOperandA; CeOperandInfoKind mOperandB; CeOperandInfoKind mOperandC; + CeOpInfoFlag mFlags; }; #define CEOPINFO_SIZED_1(OPNAME, OPINFOA) \ @@ -26,21 +33,21 @@ struct CeOpInfo {OPNAME "_16", OPINFOA}, \ {OPNAME "_32", OPINFOA}, \ {OPNAME "_64", OPINFOA}, \ - {OPNAME "_X", OPINFOA, CEOI_IMM32} + {OPNAME "_X", OPINFOA, CEOI_None, CEOI_None, CEOI_None, CeOpInfoFlag_SizeX} #define CEOPINFO_SIZED_2(OPNAME, OPINFOA, OPINFOB) \ {OPNAME "_8", OPINFOA, OPINFOB}, \ {OPNAME "_16", OPINFOA, OPINFOB}, \ {OPNAME "_32", OPINFOA, OPINFOB}, \ {OPNAME "_64", OPINFOA, OPINFOB}, \ - {OPNAME "_X", OPINFOA, CEOI_IMM32, OPINFOB} + {OPNAME "_X", OPINFOA, OPINFOB, CEOI_None, CEOI_None, CeOpInfoFlag_SizeX} #define CEOPINFO_SIZED_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \ {OPNAME "_8", OPINFOA, OPINFOB, OPINFOC}, \ {OPNAME "_16", OPINFOA, OPINFOB, OPINFOC}, \ {OPNAME "_32", OPINFOA, OPINFOB, OPINFOC}, \ {OPNAME "_64", OPINFOA, OPINFOB, OPINFOC}, \ - {OPNAME "_X", OPINFOA, CEOI_IMM32, OPINFOB, OPINFOC} + {OPNAME "_X", OPINFOA, OPINFOB, OPINFOC, CEOI_None, CeOpInfoFlag_SizeX} #define CEOPINFO_SIZED_NUMERIC_2(OPNAME, OPINFOA, OPINFOB) \ {OPNAME "_I8", OPINFOA, OPINFOB}, \ @@ -92,7 +99,8 @@ static CeOpInfo gOpInfo[] = {"FrameAddr_32", CEOI_FrameRef, CEOI_FrameRef}, {"FrameAddr_64", CEOI_FrameRef, CEOI_FrameRef}, {"FrameAddrOfs_32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32}, - {"CeOp_ConstDataRef", CEOI_FrameRef, CEOI_IMM32}, + {"ConstData", CEOI_FrameRef, CEOI_IMM32}, + {"ConstDataRef", CEOI_FrameRef, CEOI_IMM32}, {"Zero", CEOI_None, CEOI_FrameRef, CEOI_IMM32}, {"Const_8", CEOI_FrameRef, CEOI_IMM8}, @@ -307,6 +315,12 @@ void CeDumpContext::Dump() mStr += StrFormat("%04X: ", ofs); + int32 sizeX = -1; + if ((opInfo.mFlags & CeOpInfoFlag_SizeX) != 0) + { + sizeX = CE_GET(int); + } + if (opInfo.mResultKind != CEOI_None) { DumpOperandInfo(opInfo.mResultKind); @@ -314,6 +328,12 @@ void CeDumpContext::Dump() } mStr += opInfo.mName; + + if (sizeX != -1) + { + mStr += StrFormat(":%d", sizeX); + } + if (opInfo.mOperandA != CEOI_None) { mStr += " "; @@ -720,7 +740,21 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme } if (globalVar->mInitializer != NULL) - return GetOperand(globalVar->mInitializer); + { + auto result = GetOperand(globalVar->mInitializer, false, true); + if (result.mKind == CeOperandKind_ConstStructTableIdx) + { + auto& constTableEntry = mCeFunction->mConstStructTable[result.mStructTableIdx]; + auto ptrType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType); + auto dataResult = FrameAlloc(ptrType); + Emit(CeOp_ConstDataRef); + EmitFrameOffset(dataResult); + Emit((int32)result.mCallTableIdx); + return dataResult; + } + + return result; + } errorKind = CeErrorKind_GlobalVariable; errorType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType); @@ -851,7 +885,8 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme if (mConstDataMap.TryAdd(structConstant, NULL, &constDataPtr)) { CeConstStructData constStructData; - errorKind = mCeMachine->WriteConstant(constStructData.mData, structConstant); + constStructData.mQueueFixups = true; + errorKind = mCeMachine->WriteConstant(constStructData, structConstant); if (errorKind == CeErrorKind_None) { *constDataPtr = (int)mCeFunction->mConstStructTable.size(); @@ -860,17 +895,27 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme else { *constDataPtr = -1; - } + } } if (*constDataPtr != -1) { - auto ptrResult = mCeMachine->GetBeContext()->GetPointerTo(structConstant->mType); - auto result = FrameAlloc(ptrResult); - Emit(CeOp_ConstDataRef); - EmitFrameOffset(result); - Emit((int32)*constDataPtr); - return result; + if (!allowImmediate) + { + auto result = FrameAlloc(structConstant->mType); + Emit(CeOp_ConstData); + EmitFrameOffset(result); + Emit((int32)*constDataPtr); + return result; + } + else + { + CeOperand result; + result.mKind = CeOperandKind_ConstStructTableIdx; + result.mCallTableIdx = *constDataPtr; + result.mType = structConstant->mType; + return result; + } } else { @@ -1737,8 +1782,7 @@ void CeBuilder::Build() auto castedInst = (BeRetInst*)inst; if (castedInst->mRetValue != NULL) { - auto mcVal = GetOperand(castedInst->mRetValue); - + auto mcVal = GetOperand(castedInst->mRetValue); BF_ASSERT(mReturnVal.mKind == CeOperandKind_AllocaAddr); EmitSizedOp(CeOp_Move_8, mcVal, NULL, true); Emit((int32)mReturnVal.mFrameOfs); @@ -2046,16 +2090,7 @@ void CeBuilder::Build() BeConstant* constant = BeValueDynCast(castedInst->mAggVal); CeOperand mcAgg; - - if (constant == NULL) - { - mcAgg = GetOperand(castedInst->mAggVal, false, true); - if (mcAgg.mKind == CeOperandKind_ConstAgg) - { - constant = mcAgg.mConstant; - } - } - + if (constant != NULL) { result.mImmediate = 0; @@ -2557,12 +2592,15 @@ CeMachine::CeMachine(BfCompiler* compiler) mExecuteId = 0; mCurTargetSrc = NULL; mCurModule = NULL; + mCurExpectingType = NULL; mHeap = NULL; mStringCharsOffset = -1; + mAppendAllocInfo = NULL; } CeMachine::~CeMachine() { + delete mAppendAllocInfo; delete mCeModule; delete mHeap; @@ -2573,6 +2611,15 @@ CeMachine::~CeMachine() } } +BfError* CeMachine::Fail(const StringImpl& error) +{ + auto bfError = mCurModule->Fail("Unable to const-evaluate function", mCurTargetSrc); + if (bfError == NULL) + return NULL; + mCompiler->mPassInstance->MoreInfo(error); + return bfError; +} + BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str) { auto bfError = mCurModule->Fail("Unable to const-evaluate function", mCurTargetSrc); @@ -2693,12 +2740,12 @@ addr_ce CeMachine::GetConstantData(BeConstant* constant) writeConstant = gvConstant->mInitializer; } - Array data; - auto result = WriteConstant(data, writeConstant); + CeConstStructData structData; + auto result = WriteConstant(structData, writeConstant); BF_ASSERT(result == CeErrorKind_None); - uint8* ptr = CeMalloc(data.mSize); - memcpy(ptr, data.mVals, data.mSize); + uint8* ptr = CeMalloc(structData.mData.mSize); + memcpy(ptr, structData.mData.mVals, structData.mData.mSize); return (addr_ce)(ptr - mMemory.mVals); } @@ -2736,7 +2783,7 @@ addr_ce CeMachine::GetReflectType(int typeId) beValue = mCeModule->mBfIRBuilder->mBeIRCodeGen->GetBeValue(globalVar->mStreamId); } } - + if (auto constant = BeValueDynCast(beValue)) *addrPtr = GetConstantData(constant); @@ -2792,6 +2839,40 @@ BfType* CeMachine::GetBfType(int typeId) return NULL; } +void CeMachine::PrepareConstStructEntry(CeConstStructData& constEntry) +{ + if (constEntry.mHash.IsZero()) + { + constEntry.mHash = Hash128(&constEntry.mData[0], constEntry.mData.mSize); + if (!constEntry.mFixups.IsEmpty()) + constEntry.mHash = Hash128(&constEntry.mFixups[0], constEntry.mFixups.mSize * sizeof(CeConstStructFixup), constEntry.mHash); + } + + if (!constEntry.mFixups.IsEmpty()) + { + if (constEntry.mFixedData.IsEmpty()) + constEntry.mFixedData = constEntry.mData; + + for (auto& fixup : constEntry.mFixups) + { + if (fixup.mKind == CeConstStructFixup::Kind_StringPtr) + { + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeModule->ResolveTypeDef(mCompiler->mStringTypeDef, BfPopulateType_Data); + addr_ce addrPtr = GetString(fixup.mValue); + *(addr_ce*)(constEntry.mFixedData.mVals + fixup.mOffset) = addrPtr; + } + else if (fixup.mKind == CeConstStructFixup::Kind_StringCharPtr) + { + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeModule->ResolveTypeDef(mCompiler->mStringTypeDef, BfPopulateType_Data); + addr_ce addrPtr = GetString(fixup.mValue); + *(addr_ce*)(constEntry.mFixedData.mVals + fixup.mOffset) = addrPtr + stringTypeInst->mInstSize; + } + } + } + + constEntry.mBindExecuteId = mExecuteId; +} + BeContext* CeMachine::GetBeContext() { if (mCeModule == NULL) @@ -2858,38 +2939,138 @@ void CeMachine::RemoveMethod(BfMethodInstance* methodInstance) } } -int CeMachine::GetConstantSize(BfConstant* constant) -{ +//#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1) +#define CE_GETC(T) *(T*)(mMemory.mVals + addr) + +bool CeMachine::WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type) +{ switch (constant->mTypeCode) { case BfTypeCode_Int8: case BfTypeCode_UInt8: case BfTypeCode_Boolean: case BfTypeCode_Char8: - return 1; + CE_GETC(int8) = constant->mInt8; + return true; case BfTypeCode_Int16: case BfTypeCode_UInt16: case BfTypeCode_Char16: - return 2; + CE_GETC(int16) = constant->mInt16; + return true; case BfTypeCode_Int32: case BfTypeCode_UInt32: case BfTypeCode_Char32: - return 4; + CE_GETC(int32) = constant->mInt32; + return true; case BfTypeCode_Int64: - case BfTypeCode_UInt64: - return 8; + case BfTypeCode_UInt64: + CE_GETC(int64) = constant->mInt64; + return true; case BfTypeCode_NullPtr: - return 4; + if (mCeModule->mSystem->mPtrSize == 4) + CE_GETC(int32) = 0; + else + CE_GETC(int64) = 0; + return true; case BfTypeCode_Float: - return 4; + CE_GETC(float) = (float)constant->mDouble; + return true; case BfTypeCode_Double: - return 8; + CE_GETC(double) = constant->mDouble; + return true; } - return -1; + if (constant->mConstType == BfConstType_Agg) + { + auto aggConstant = (BfConstantAgg*)constant; + if (type->IsSizedArray()) + { + return false; + } + else + { + BF_ASSERT(type->IsStruct()); + + module->PopulateType(type); + auto typeInst = type->ToTypeInstance(); + int idx = 0; + + if (typeInst->mBaseType != NULL) + { + auto baseConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[0]); + WriteConstant(module, addr, baseConstant, typeInst->mBaseType); + } + + for (auto& fieldInstance : typeInst->mFieldInstances) + { + if (fieldInstance.mDataOffset < 0) + continue; + + auto fieldConstant = module->mBfIRBuilder->GetConstant(aggConstant->mValues[fieldInstance.mDataIdx]); + if (fieldConstant == NULL) + return false; + WriteConstant(module, addr + fieldInstance.mDataOffset, fieldConstant, fieldInstance.mResolvedType); + } + } + return true; + } + + if (constant->mConstType == BfConstType_AggZero) + { + BF_ASSERT(type->IsComposite()); + memset(mMemory.mVals + addr, 0, type->mSize); + return true; + } + + if (constant->mConstType == BfConstType_BitCast) + { + auto constBitCast = (BfConstantBitCast*)constant; + + auto constTarget = module->mBfIRBuilder->GetConstantById(constBitCast->mTarget); + return WriteConstant(module, addr, constTarget, type); + } + + if (constant->mConstType == BfConstType_GEP32_2) + { + auto gepConst = (BfConstantGEP32_2*)constant; + auto constTarget = module->mBfIRBuilder->GetConstantById(gepConst->mTarget); + if (constTarget->mConstType == BfConstType_GlobalVar) + { + auto globalVar = (BfGlobalVar*)constTarget; + if (strncmp(globalVar->mName, "__bfStrData", 10) == 0) + { + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeModule->ResolveTypeDef(mCompiler->mStringTypeDef, BfPopulateType_Data); + + int stringId = atoi(globalVar->mName + 11); + addr_ce strAddr = GetString(stringId) + stringTypeInst->mInstSize; + if (mCeModule->mSystem->mPtrSize == 4) + CE_GETC(int32) = strAddr; + else + CE_GETC(int64) = strAddr; + return true; + } + } + } + + if (constant->mConstType == BfConstType_GlobalVar) + { + auto globalVar = (BfGlobalVar*)constant; + if (strncmp(globalVar->mName, "__bfStrObj", 10) == 0) + { + int stringId = atoi(globalVar->mName + 10); + addr_ce strAddr = GetString(stringId); + if (mCeModule->mSystem->mPtrSize == 4) + CE_GETC(int32) = strAddr; + else + CE_GETC(int64) = strAddr; + return true; + } + } + + return false; } -CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) +CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constVal) { auto beType = constVal->GetType(); if (auto globalVar = BeValueDynCast(constVal)) @@ -2899,7 +3080,7 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) int stringId = atoi(globalVar->mName.c_str() + 10); addr_ce stringAddr = GetString(stringId); - auto ptr = arr.GrowUninitialized(mCeModule->mSystem->mPtrSize); + auto ptr = data.mData.GrowUninitialized(mCeModule->mSystem->mPtrSize); int64 addr64 = stringAddr; memcpy(ptr, &addr64, mCeModule->mSystem->mPtrSize); return CeErrorKind_None; @@ -2908,16 +3089,18 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) if (globalVar->mInitializer == NULL) return CeErrorKind_GlobalVariable; - //uint8* gvData = CeMalloc(globalVar->mType->mSize); - Array gvData; + + BF_ASSERT(!data.mQueueFixups); + CeConstStructData gvData; + auto result = WriteConstant(gvData, globalVar->mInitializer); if (result != CeErrorKind_None) return result; - uint8* gvPtr = CeMalloc(gvData.mSize); - memcpy(gvPtr, gvData.mVals, gvData.mSize); + uint8* gvPtr = CeMalloc(gvData.mData.mSize); + memcpy(gvPtr, gvData.mData.mVals, gvData.mData.mSize); - auto ptr = arr.GrowUninitialized(mCeModule->mSystem->mPtrSize); + auto ptr = data.mData.GrowUninitialized(mCeModule->mSystem->mPtrSize); int64 addr64 = (addr_ce)(gvPtr - mMemory.mVals); memcpy(ptr, &addr64, mCeModule->mSystem->mPtrSize); return CeErrorKind_None; @@ -2928,7 +3111,7 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) } else if (auto constStruct = BeValueDynCast(constVal)) { - int startOfs = arr.mSize; + int startOfs = data.mData.mSize; if (constStruct->mType->mTypeCode == BeTypeCode_Struct) { BeStructType* structType = (BeStructType*)constStruct->mType; @@ -2937,22 +3120,22 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) { auto& member = structType->mMembers[memberIdx]; // Do any per-member alignment - int wantZeroes = member.mByteOffset - (arr.mSize - startOfs); + int wantZeroes = member.mByteOffset - (data.mData.mSize - startOfs); if (wantZeroes > 0) - arr.Insert(arr.size(), (uint8)0, wantZeroes); + data.mData.Insert(data.mData.size(), (uint8)0, wantZeroes); - auto result = WriteConstant(arr, constStruct->mMemberValues[memberIdx]); + auto result = WriteConstant(data, constStruct->mMemberValues[memberIdx]); if (result != CeErrorKind_None) return result; } // Do end padding - arr.Insert(arr.size(), (uint8)0, structType->mSize - (arr.mSize - startOfs)); + data.mData.Insert(data.mData.size(), (uint8)0, structType->mSize - (data.mData.mSize - startOfs)); } else if (constStruct->mType->mTypeCode == BeTypeCode_SizedArray) { for (auto& memberVal : constStruct->mMemberValues) { - auto result = WriteConstant(arr, memberVal); + auto result = WriteConstant(data, memberVal); if (result != CeErrorKind_None) return result; } @@ -2962,11 +3145,11 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) } else if (auto constStr = BeValueDynCast(constVal)) { - arr.Insert(arr.mSize, (uint8*)constStr->mString.c_str(), (int)constStr->mString.length() + 1); + data.mData.Insert(data.mData.mSize, (uint8*)constStr->mString.c_str(), (int)constStr->mString.length() + 1); } else if (auto constCast = BeValueDynCast(constVal)) { - auto result = WriteConstant(arr, constCast->mTarget); + auto result = WriteConstant(data, constCast->mTarget); if (result != CeErrorKind_None) return result; } @@ -2991,7 +3174,38 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) { BF_FATAL("Invalid GEP"); } - + + addr_ce addr = -1; + + if (globalVar->mName.StartsWith("__bfStrData")) + { + int stringId = atoi(globalVar->mName.c_str() + 11); + + if (data.mQueueFixups) + { + addr = 0; + CeConstStructFixup fixup; + fixup.mKind = CeConstStructFixup::Kind_StringCharPtr; + fixup.mValue = stringId; + fixup.mOffset = (int)data.mData.mSize; + data.mFixups.Add(fixup); + } + else + { + addr_ce stringAddr = GetString(stringId); + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeModule->ResolveTypeDef(mCeModule->mCompiler->mStringTypeDef, BfPopulateType_Data); + addr = stringAddr + stringTypeInst->mInstSize; + } + } + + if (addr != -1) + { + auto ptr = data.mData.GrowUninitialized(mCeModule->mSystem->mPtrSize); + int64 addr64 = addr + dataOfs; + memcpy(ptr, &addr64, mCeModule->mSystem->mPtrSize); + return CeErrorKind_None; + } + return CeErrorKind_GlobalVariable; // auto sym = GetSymbol(globalVar); @@ -3008,7 +3222,8 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) BF_FATAL("Invalid GEPConstant"); } } - else if ((beType->IsPointer()) && (constVal->mTarget != NULL)) + + /*else if ((beType->IsPointer()) && (constVal->mTarget != NULL)) { auto result = WriteConstant(arr, constVal->mTarget); if (result != CeErrorKind_None) @@ -3027,52 +3242,225 @@ CeErrorKind CeMachine::WriteConstant(Array& arr, BeConstant* constVal) memset(ptr, 0, writeSize); sizeLeft -= writeSize; } + }*/ + + else if (BeValueDynCastExact(constVal) != NULL) + { + if (constVal->mType->IsStruct()) + { + if (constVal->mType->mSize > 0) + { + auto ptr = data.mData.GrowUninitialized(constVal->mType->mSize); + memset(ptr, 0, constVal->mType->mSize); + } + } + else + { + auto ptr = data.mData.GrowUninitialized(beType->mSize); + memcpy(ptr, &constVal->mInt64, beType->mSize); + } } else - { - auto ptr = arr.GrowUninitialized(beType->mSize); - memcpy(ptr, &constVal->mInt64, beType->mSize); - } + return CeErrorKind_Error; + return CeErrorKind_None; } -#define CE_GETC(T) *((T*)(ptr += sizeof(T)) - 1) -void CeMachine::WriteConstant(uint8* ptr, BfConstant* constant) -{ - switch (constant->mTypeCode) - { - case BfTypeCode_Int8: - case BfTypeCode_UInt8: - case BfTypeCode_Boolean: - case BfTypeCode_Char8: - CE_GETC(int8) = constant->mInt8; - return; - case BfTypeCode_Int16: - case BfTypeCode_UInt16: - case BfTypeCode_Char16: - CE_GETC(int16) = constant->mInt16; - return; - case BfTypeCode_Int32: - case BfTypeCode_UInt32: - case BfTypeCode_Char32: - CE_GETC(int32) = constant->mInt32; - return; - case BfTypeCode_Int64: - case BfTypeCode_UInt64: - CE_GETC(int64) = constant->mInt64; - return; - case BfTypeCode_NullPtr: - CE_GETC(int32) = 0; - return; - case BfTypeCode_Float: - CE_GETC(float) = (float)constant->mDouble; - return; - case BfTypeCode_Double: - CE_GETC(double) = constant->mDouble; - return; +#define CE_CREATECONST_CHECKPTR(PTR, SIZE) \ + if ((((uint8*)(PTR) - memStart) - 0x10000) + (SIZE) > (memSize - 0x10000)) \ + { \ + Fail("Access violation creating constant result"); \ + return BfIRValue(); \ } + +BfIRValue CeMachine::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType, BfType** outType) +{ + BfIRBuilder* irBuilder = module->mBfIRBuilder; + + uint8* memStart = mMemory.mVals; + int memSize = mMemory.mSize; + + if (bfType->IsPrimitiveType()) + { + auto primType = (BfPrimitiveType*)bfType; + + auto typeCode = primType->mTypeDef->mTypeCode; + if (typeCode == BfTypeCode_IntPtr) + typeCode = (mCeModule->mCompiler->mSystem->mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64; + else if (typeCode == BfTypeCode_UIntPtr) + typeCode = (mCeModule->mCompiler->mSystem->mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64; + + switch (typeCode) + { + case BfTypeCode_Int8: + CE_CREATECONST_CHECKPTR(ptr, sizeof(int8)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr); + case BfTypeCode_UInt8: + CE_CREATECONST_CHECKPTR(ptr, sizeof(uint8)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(uint8*)ptr); + case BfTypeCode_Int16: + CE_CREATECONST_CHECKPTR(ptr, sizeof(int16)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int16*)ptr); + case BfTypeCode_UInt16: + CE_CREATECONST_CHECKPTR(ptr, sizeof(uint16)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(uint16*)ptr); + case BfTypeCode_Int32: + CE_CREATECONST_CHECKPTR(ptr, sizeof(int32)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int32*)ptr); + case BfTypeCode_UInt32: + CE_CREATECONST_CHECKPTR(ptr, sizeof(uint32)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)*(uint32*)ptr); + case BfTypeCode_Int64: + case BfTypeCode_UInt64: + CE_CREATECONST_CHECKPTR(ptr, sizeof(int64)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)ptr); + case BfTypeCode_Float: + CE_CREATECONST_CHECKPTR(ptr, sizeof(float)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(float*)ptr); + case BfTypeCode_Double: + CE_CREATECONST_CHECKPTR(ptr, sizeof(double)); + return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(double*)ptr); + } + + return BfIRValue(); + } + + if (bfType->IsTypeInstance()) + { + auto typeInst = bfType->ToTypeInstance(); + + uint8* instData = ptr; +// if ((typeInst->IsObject()) && (!isBaseType)) +// { +// CE_CREATECONST_CHECKPTR(ptr, sizeof(addr_ce)); +// instData = mMemory.mVals + *(addr_ce*)ptr; +// CE_CREATECONST_CHECKPTR(instData, typeInst->mInstSize); +// } + + if (typeInst->IsInstanceOf(mCompiler->mStringTypeDef)) + { + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeModule->ResolveTypeDef(mCompiler->mStringTypeDef, BfPopulateType_Data); + module->PopulateType(stringTypeInst); + + auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize; + auto lenOffset = stringTypeInst->mFieldInstances[0].mDataOffset; + auto allocSizeOffset = stringTypeInst->mFieldInstances[1].mDataOffset; + auto ptrOffset = stringTypeInst->mFieldInstances[2].mDataOffset; + + int32 lenVal = *(int32*)(instData + lenOffset); + + char* charPtr = NULL; + + if (lenByteCount == 4) + { + int32 allocSizeVal = *(int32*)(instData + allocSizeOffset); + if ((allocSizeVal & 0x40000000) != 0) + { + int32 ptrVal = *(int32*)(instData + ptrOffset); + charPtr = (char*)(ptrVal + memStart); + } + else + { + charPtr = (char*)(instData + ptrOffset); + } + } + + CE_CREATECONST_CHECKPTR(charPtr, lenVal); + String str(charPtr, lenVal); + return module->GetStringObjectValue(str); + } + + SizedArray fieldVals; + + if (typeInst->IsInstanceOf(mCeModule->mCompiler->mSpanTypeDef)) + { + if ((outType != NULL) && (mCurExpectingType->IsSizedArray())) + { + module->PopulateType(typeInst); + + auto ptrOffset = typeInst->mFieldInstances[0].mDataOffset; + auto lenOffset = typeInst->mFieldInstances[1].mDataOffset; + + BfType* elemType = typeInst->GetUnderlyingType(); + + CE_CREATECONST_CHECKPTR(instData, mCeModule->mSystem->mPtrSize * 2); + addr_ce addr = *(addr_ce*)(instData + ptrOffset); + int32 lenVal = *(int32*)(instData + lenOffset); + CE_CREATECONST_CHECKPTR(memStart + addr, lenVal); + + for (int i = 0; i < lenVal; i++) + { + auto result = CreateConstant(module, memStart + addr + i * elemType->GetStride(), elemType); + if (!result) + return BfIRValue(); + fieldVals.Add(result); + } + + auto irArrayType = irBuilder->GetSizedArrayType(irBuilder->MapType(elemType, BfIRPopulateType_Full), lenVal); + auto instResult = irBuilder->CreateConstAgg(irArrayType, fieldVals); + *outType = module->CreateSizedArrayType(elemType, lenVal); + return instResult; + } + } + + if (typeInst->IsObjectOrInterface()) + { + Fail(StrFormat("Reference type '%s' return value not allowed", module->TypeToString(typeInst).c_str())); + return BfIRValue(); + } + + if (typeInst->IsPointer()) + { + Fail(StrFormat("Pointer type '%s' return value not allowed", module->TypeToString(typeInst).c_str())); + return BfIRValue(); + } + + if (typeInst->mBaseType != NULL) + { + auto result = CreateConstant(module, instData, typeInst->mBaseType); + if (!result) + return BfIRValue(); + fieldVals.Add(result); + } + + for (int fieldIdx = 0; fieldIdx < typeInst->mFieldInstances.size(); fieldIdx++) + { + auto& fieldInstance = typeInst->mFieldInstances[fieldIdx]; + if (fieldInstance.mDataOffset < 0) + continue; + + if ((fieldInstance.mDataOffset == 0) && (typeInst == mCompiler->mContext->mBfObjectType)) + { + auto vdataPtr = module->GetClassVDataPtr(typeInst); + if (fieldInstance.mResolvedType->IsInteger()) + fieldVals.Add(irBuilder->CreatePtrToInt(vdataPtr, ((BfPrimitiveType*)fieldInstance.mResolvedType)->mTypeDef->mTypeCode)); + else + fieldVals.Add(vdataPtr); + continue; + } + + auto result = CreateConstant(module, instData + fieldInstance.mDataOffset, fieldInstance.mResolvedType); + if (!result) + return BfIRValue(); + + if (fieldInstance.mDataIdx == fieldVals.mSize) + fieldVals.Add(result); + else + { + while (fieldInstance.mDataIdx >= fieldVals.mSize) + fieldVals.Add(BfIRValue()); + fieldVals[fieldInstance.mDataIdx] = result; + } + } + + auto instResult = irBuilder->CreateConstAgg(irBuilder->MapTypeInst(typeInst, BfIRPopulateType_Full), fieldVals); + return instResult; + } + + return BfIRValue(); } + #define CE_CHECKSTACK() \ if (stackPtr < memStart) \ { \ @@ -3087,6 +3475,12 @@ void CeMachine::WriteConstant(uint8* ptr, BfConstant* constant) } // This check will fail for addresses < 64K (null pointer), or out-of-bounds +#define CE_CHECKSIZE(SIZE) \ + if ((SIZE) < 0) \ + { \ + _Fail("Invalid memory size"); \ + return false; \ + } #define CE_CHECKADDR(ADDR, SIZE) \ if (((ADDR) - 0x10000) + (SIZE) > (memSize - 0x10000)) \ { \ @@ -3606,6 +4000,8 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto destAddr = CE_GETFRAME(addr_ce); uint8 setValue = CE_GETFRAME(uint8); int32 setSize = CE_GETFRAME(int32); + CE_CHECKSIZE(setSize); + CE_CHECKADDR(destAddr, setSize); memset(memStart + destAddr, setValue, setSize); } break; @@ -3614,6 +4010,8 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto destAddr = CE_GETFRAME(addr_ce); uint8 setValue = CE_GETINST(uint8); int32 setSize = CE_GETINST(int32); + CE_CHECKSIZE(setSize); + CE_CHECKADDR(destAddr, setSize); memset(memStart + destAddr, setValue, setSize); } break; @@ -3622,6 +4020,9 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto destAddr = CE_GETFRAME(addr_ce); auto srcAddr = CE_GETFRAME(addr_ce); int32 size = CE_GETFRAME(int32); + CE_CHECKSIZE(size); + CE_CHECKADDR(srcAddr, size); + CE_CHECKADDR(destAddr, size); memcpy(memStart + destAddr, memStart + srcAddr, size); } break; @@ -3640,6 +4041,21 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* result = (int32)(addr - memStart + ofs); } break; + case CeOp_ConstData: + { + auto frameOfs = CE_GETINST(int32); + int32 constIdx = CE_GETINST(int32); + auto& constEntry = ceFunction->mConstStructTable[constIdx]; + + if (constEntry.mBindExecuteId != mExecuteId) + { + PrepareConstStructEntry(constEntry); + _FixVariables(); + } + auto& buff = (constEntry.mFixedData.mSize > 0) ? constEntry.mFixedData : constEntry.mData; + memcpy(framePtr + frameOfs, buff.mVals, buff.mSize); + } + break; case CeOp_ConstDataRef: { auto frameOfs = CE_GETINST(int32); @@ -3647,15 +4063,17 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto& constEntry = ceFunction->mConstStructTable[constIdx]; if (constEntry.mBindExecuteId != mExecuteId) { - if (constEntry.mHash.IsZero()) - constEntry.mHash = Hash128(&constEntry.mData[0], constEntry.mData.mSize); + PrepareConstStructEntry(constEntry); + _FixVariables(); + auto& buff = (constEntry.mFixedData.mSize > 0) ? constEntry.mFixedData : constEntry.mData; + addr_ce* constAddrPtr = NULL; if (mConstDataMap.TryAdd(constEntry.mHash, NULL, &constAddrPtr)) { - uint8* data = CeMalloc(constEntry.mData.mSize); + uint8* data = CeMalloc(buff.mSize); _FixVariables(); - memcpy(data, &constEntry.mData[0], constEntry.mData.mSize); + memcpy(data, &buff[0], buff.mSize); *constAddrPtr = (addr_ce)(data - memStart); } @@ -3699,7 +4117,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* case CeOp_Const_X: { int32 constSize = CE_GETINST(int32); - auto resultPtr = &CE_GETFRAME(uint8); + auto resultPtr = &CE_GETFRAME(uint8); memcpy(resultPtr, instPtr, constSize); instPtr += constSize; } @@ -3714,7 +4132,16 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CE_LOAD(uint32); break; case CeOp_Load_64: - CE_LOAD(uint64); + CE_LOAD(uint64); + break; + case CeOp_Load_X: + { + int32 size = CE_GETINST(int32); + auto resultPtr = &CE_GETFRAME(uint8); + auto ceAddr = CE_GETFRAME(addr_ce); + CE_CHECKADDR(ceAddr, size); + memcpy(resultPtr, memStart + ceAddr, size); + } break; case CeOp_Store_8: CE_STORE(uint8); @@ -3781,6 +4208,14 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* case CeOp_Pop_64: CEOP_POP(int64); break; + case CeOp_Pop_X: + { + int32 size = CE_GETINST(int32); + auto resultPtr = &CE_GETFRAME(uint8); + memcpy(resultPtr, stackPtr, size); + stackPtr += size; + } + break; case CeOp_AdjustSP: { int32 adjust = CE_GETFRAME(int32); @@ -3884,7 +4319,9 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } break; case CeOp_GetMethod: - { + { + BF_ASSERT(memStart == mMemory.mVals); + auto& result = CE_GETFRAME(CeFunction*); int32 callIdx = CE_GETINST(int32); auto& callEntry = ceFunction->mCallTable[callIdx]; @@ -3896,7 +4333,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (callEntry.mFunctionInfo == NULL) { _Fail("Unable to locate function entry"); - break; + return false; } if ((callEntry.mFunctionInfo->mCeFunction == NULL) && (!callEntry.mFunctionInfo->mMethodRef.IsNull())) @@ -3915,7 +4352,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (callEntry.mFunctionInfo->mCeFunction == NULL) { _Fail("Method not generated"); - break; + return false; } callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction; @@ -3927,6 +4364,7 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* callEntry.mBindRevision = mRevision; } + BF_ASSERT(memStart == mMemory.mVals); result = callEntry.mFunction; // if (callEntry.mFunction->mName.Contains("__static_dump")) // { @@ -4550,7 +4988,10 @@ bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder) -{ +{ + if (mHeap == NULL) + mHeap = new ContiguousHeap(); + if (ceFunction->mMethodInstance != NULL) { auto methodDef = ceFunction->mMethodInstance->mMethodDef; @@ -4731,29 +5172,59 @@ void CeMachine::QueueStaticField(BfFieldInstance* fieldInstance, const StringImp mStaticFieldMap[mangledFieldName] = staticFieldInfo; } -BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags) -{ -// for (int argIdx = 0; argIdx < (int)args.size(); argIdx++) -// { -// auto arg = args[argIdx]; -// if (!arg.IsConst()) -// return BfTypedValue(); -// } +void CeMachine::SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue) +{ + delete mAppendAllocInfo; + mAppendAllocInfo = new CeAppendAllocInfo(); + mAppendAllocInfo->mModule = module; + mAppendAllocInfo->mAllocValue = allocValue; + mAppendAllocInfo->mAppendSizeValue = appendSizeValue; +} +void CeMachine::ClearAppendAllocInfo() +{ + delete mAppendAllocInfo; + mAppendAllocInfo = NULL; +} + +BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags, BfType* expectingType) +{ // DISABLED return BfTypedValue(); + if (mAppendAllocInfo != NULL) + { + if ((mAppendAllocInfo->mAppendSizeValue) && (!mAppendAllocInfo->mAppendSizeValue.IsConst())) + return BfTypedValue(); + } + + int thisArgIdx = -1; + int appendAllocIdx = -1; + if (methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor) + { + if (!methodInstance->GetOwner()->IsValuelessType()) + thisArgIdx = 0; + if ((methodInstance->GetParamCount() >= 1) && (methodInstance->GetParamKind(0) == BfParamKind_AppendIdx)) + appendAllocIdx = 1; + } + + for (int argIdx = 0; argIdx < (int)args.size(); argIdx++) + { + auto arg = args[argIdx]; + if (!arg.IsConst()) + { + if ((argIdx != thisArgIdx) && (argIdx != appendAllocIdx)) + return BfTypedValue(); + } + } + SetAndRestoreValue prevTargetSrc(mCurTargetSrc, targetSrc); SetAndRestoreValue prevModule(mCurModule, module); + SetAndRestoreValue prevExpectingType(mCurExpectingType, expectingType); BF_ASSERT(mCallStack.IsEmpty()); - auto methodDef = methodInstance->mMethodDef; - if (!methodDef->mIsStatic) - { - if (!methodInstance->GetOwner()->IsValueType()) - return BfTypedValue(); - } + auto methodDef = methodInstance->mMethodDef; if (mCeModule == NULL) Init(); @@ -4763,29 +5234,141 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns if (!ceFunction->mInitialized) PrepareFunction(ceFunction, NULL); - if (mHeap == NULL) - mHeap = new ContiguousHeap(); mMemory.Resize(BF_CE_STACK_SIZE); auto stackPtr = &mMemory[0] + mMemory.mSize; - auto* memStart = &mMemory[0]; + auto* memStart = &mMemory[0]; + BfTypeInstance* thisType = methodInstance->GetOwner(); + addr_ce allocThisInstAddr = 0; + addr_ce allocThisAddr = 0; + int allocThisSize = -1; + + if (thisArgIdx != -1) + { + allocThisSize = thisType->mInstSize; + + if ((mAppendAllocInfo != NULL) && (mAppendAllocInfo->mAppendSizeValue)) + { + BF_ASSERT(mAppendAllocInfo->mModule == module); + BF_ASSERT(mAppendAllocInfo->mAppendSizeValue.IsConst()); + + auto appendSizeConstant = module->mBfIRBuilder->GetConstant(mAppendAllocInfo->mAppendSizeValue); + BF_ASSERT(module->mBfIRBuilder->IsInt(appendSizeConstant->mTypeCode)); + allocThisSize += appendSizeConstant->mInt32; + } + + stackPtr -= allocThisSize; + auto allocThisPtr = stackPtr; + memset(allocThisPtr, 0, allocThisSize); + + if (thisType->IsObject()) + *(int32*)(allocThisPtr) = thisType->mTypeId; + + allocThisInstAddr = allocThisPtr - memStart; + allocThisAddr = allocThisInstAddr; + } + + addr_ce allocAppendIdxAddr = 0; + if (appendAllocIdx != -1) + { + stackPtr -= mCeModule->mSystem->mPtrSize; + memset(stackPtr, 0, mCeModule->mSystem->mPtrSize); + allocAppendIdxAddr = stackPtr - memStart; + } + + auto _FixVariables = [&]() + { + intptr memOffset = &mMemory[0] - memStart; + if (memOffset == 0) + return; + memStart += memOffset; + stackPtr += memOffset; + }; + + addr_ce compositeStartAddr = stackPtr - memStart; + int paramIdx = methodInstance->GetParamCount(); + for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--) + { + BfType* paramType = NULL; + while (true) + { + paramIdx--; + paramType = methodInstance->GetParamType(paramIdx); + if (paramType->IsTypedPrimitive()) + paramType = paramType->GetUnderlyingType(); + if (!paramType->IsValuelessType()) + break; + } + if (paramType->IsComposite()) + { + auto paramTypeInst = paramType->ToTypeInstance(); + stackPtr -= paramTypeInst->mInstSize; + } + } + + addr_ce useCompositeAddr = compositeStartAddr; + paramIdx = methodInstance->GetParamCount(); for (int argIdx = (int)args.size() - 1; argIdx >= 0; argIdx--) { + BfType* paramType = NULL; + while (true) + { + paramIdx--; + paramType = methodInstance->GetParamType(paramIdx); + if (paramType->IsTypedPrimitive()) + paramType = paramType->GetUnderlyingType(); + if (!paramType->IsValuelessType()) + break; + } + auto arg = args[argIdx]; - if (!arg.IsConst()) - return BfTypedValue(); - - auto constant = module->mBfIRBuilder->GetConstant(arg); - int constSize = GetConstantSize(constant); - if (constSize == -1) - return BfTypedValue(); + if (!arg.IsConst()) + { + if (argIdx == thisArgIdx) + { + if (mAppendAllocInfo != NULL) + BF_ASSERT(mAppendAllocInfo->mAllocValue == arg); - stackPtr -= constSize; - WriteConstant(stackPtr, constant); + stackPtr -= mCeModule->mSystem->mPtrSize; + int64 addr64 = allocThisAddr; + memcpy(stackPtr, &addr64, mCeModule->mSystem->mPtrSize); + continue; + } + else if (argIdx == appendAllocIdx) + { + stackPtr -= mCeModule->mSystem->mPtrSize; + int64 addr64 = allocAppendIdxAddr; + memcpy(stackPtr, &addr64, mCeModule->mSystem->mPtrSize); + continue; + } + else + return BfTypedValue(); + } + + auto constant = module->mBfIRBuilder->GetConstant(arg); + if (paramType->IsComposite()) + { + auto paramTypeInst = paramType->ToTypeInstance(); + useCompositeAddr -= paramTypeInst->mInstSize; + if (!WriteConstant(module, useCompositeAddr, constant, paramType)) + return BfTypedValue(); + _FixVariables(); + + stackPtr -= mCeModule->mSystem->mPtrSize; + int64 addr64 = useCompositeAddr; + memcpy(stackPtr, &addr64, mCeModule->mSystem->mPtrSize); + } + else + { + stackPtr -= paramType->mSize; + if (!WriteConstant(module, stackPtr - memStart, constant, paramType)) + return BfTypedValue(); + _FixVariables(); + } } - addr_ce retAddr = 0; + addr_ce retAddr = 0; auto returnType = methodInstance->mReturnType; if (!returnType->IsValuelessType()) { @@ -4796,64 +5379,32 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr); memStart = &mMemory[0]; - - auto constHolder = module->mBfIRBuilder; + + addr_ce retInstAddr = retAddr; + if ((returnType->IsObject()) || (returnType->IsPointer())) + { + // Or pointer? + retInstAddr = *(addr_ce*)(memStart + retAddr); + } BfTypedValue returnValue; if (success) { BfTypedValue retValue; - if (retAddr != 0) + if ((retInstAddr != 0) || (allocThisInstAddr != 0)) { - auto* retPtr = memStart + retAddr; - BfIRValue constVal; - - if (returnType->IsPrimitiveType()) - { - auto primType = (BfPrimitiveType*)returnType; - - auto typeCode = primType->mTypeDef->mTypeCode; - if (typeCode == BfTypeCode_IntPtr) - typeCode = (module->mCompiler->mSystem->mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64; - else if (typeCode == BfTypeCode_UIntPtr) - typeCode = (module->mCompiler->mSystem->mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64; - - switch (typeCode) - { - case BfTypeCode_Int8: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(int8*)retPtr); - break; - case BfTypeCode_UInt8: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(uint8*)retPtr); - break; - case BfTypeCode_Int16: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(int16*)retPtr); - break; - case BfTypeCode_UInt16: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(uint16*)retPtr); - break; - case BfTypeCode_Int32: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(int32*)retPtr); - break; - case BfTypeCode_UInt32: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)*(uint32*)retPtr); - break; - case BfTypeCode_Int64: - case BfTypeCode_UInt64: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)retPtr); - break; - case BfTypeCode_Float: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(float*)retPtr); - break; - case BfTypeCode_Double: - constVal = constHolder->CreateConst(primType->mTypeDef->mTypeCode, *(double*)retPtr); - break; - } + auto* retPtr = memStart + retInstAddr; + if (allocThisInstAddr != 0) + { + retPtr = memStart + allocThisAddr; + returnType = thisType; } + BfType* usedReturnType = returnType; + BfIRValue constVal = CreateConstant(module, retPtr, returnType, &usedReturnType); if (constVal) - returnValue = BfTypedValue(constVal, returnType); + returnValue = BfTypedValue(constVal, usedReturnType); } else { @@ -4870,7 +5421,7 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns mCallStack.Clear(); mStaticCtorExecSet.Clear(); mStaticFieldMap.Clear(); - mHeap->Clear(BF_CE_MAX_CARRYOVER_HEAP); + mHeap->Clear(BF_CE_MAX_CARRYOVER_HEAP); return returnValue; } diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 7e65f3fd..d4f9c231 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -55,6 +55,7 @@ typedef int addr_ce; enum CeErrorKind { CeErrorKind_None, + CeErrorKind_Error, CeErrorKind_GlobalVariable, CeErrorKind_FunctionPointer, CeErrorKind_Intrinsic @@ -83,6 +84,7 @@ enum CeOp : int16 CeOp_FrameAddr_64, CeOp_FrameAddrOfs_32, + CeOp_ConstData, CeOp_ConstDataRef, CeOp_Zero, CEOP_SIZED(Const), @@ -255,19 +257,39 @@ enum CeFunctionKind CeFunctionKind_Char32_IsNumber, }; +class CeConstStructFixup +{ +public: + enum Kind + { + Kind_None, + Kind_StringPtr, + Kind_StringCharPtr, + }; + +public: + Kind mKind; + int mValue; + int mOffset; +}; + class CeConstStructData { public: Val128 mHash; Array mData; + Array mFixedData; + Array mFixups; addr_ce mAddr; int mBindExecuteId; + bool mQueueFixups; public: CeConstStructData() { mBindExecuteId = -1; mAddr = 0; + mQueueFixups = false; } }; @@ -336,7 +358,8 @@ public: enum CeEvalFlags { - CeEvalFlags_None = 0 + CeEvalFlags_None = 0, + CeEvalFlags_Cascade = 1 }; enum CeOperandKind @@ -346,7 +369,7 @@ enum CeOperandKind CeOperandKind_AllocaAddr, CeOperandKind_Block, CeOperandKind_Immediate, - CeOperandKind_ConstAgg, + CeOperandKind_ConstStructTableIdx, CeOperandKind_CallTableIdx }; @@ -360,6 +383,7 @@ public: int mBlockIdx; int mImmediate; int mCallTableIdx; + int mStructTableIdx; BeConstant* mConstant; }; BeType* mType; @@ -462,7 +486,7 @@ public: CeMachine* mCeMachine; CeFunction* mCeFunction; BeFunction* mBeFunction; - CeOperand mReturnVal; + CeOperand mReturnVal; BeType* mIntPtrType; int mPtrSize; @@ -554,6 +578,14 @@ public: } }; +class CeAppendAllocInfo +{ +public: + BfModule* mModule; + BfIRValue mAllocValue; + BfIRValue mAppendSizeValue; +}; + class CeMachine { public: @@ -575,14 +607,17 @@ public: Dictionary mConstDataMap; Dictionary mStaticFieldMap; HashSet mStaticCtorExecSet; + CeAppendAllocInfo* mAppendAllocInfo; BfAstNode* mCurTargetSrc; BfModule* mCurModule; + BfType* mCurExpectingType; public: CeMachine(BfCompiler* compiler); ~CeMachine(); - + + BfError* Fail(const StringImpl& error); BfError* Fail(const CeFrame& curFrame, const StringImpl& error); void Init(); @@ -592,14 +627,15 @@ public: addr_ce GetString(int stringId); addr_ce GetConstantData(BeConstant* constant); BfType* GetBfType(int typeId); + void PrepareConstStructEntry(CeConstStructData& constStructData); BeContext* GetBeContext(); BeModule* GetBeModule(); void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo); - void RemoveMethod(BfMethodInstance* methodInstance); - int GetConstantSize(BfConstant* constant); - CeErrorKind WriteConstant(Array& arr, BeConstant* constVal); - void WriteConstant(uint8* ptr, BfConstant* constant); + void RemoveMethod(BfMethodInstance* methodInstance); + bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type); + CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal); + BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL); void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction); bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr); @@ -612,7 +648,11 @@ public: void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func); void QueueMethod(BfModuleMethodInstance moduleMethodInstance); void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName); - BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags); + + void SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue); + void ClearAppendAllocInfo(); + + BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags, BfType* expectingType); }; NS_BF_END