| 10915 | } |
| 10916 | |
| 10917 | void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds) |
| 10918 | { |
| 10919 | if (mBfIRBuilder->mIgnoreWrites) |
| 10920 | return; // Nothing needed here |
| 10921 | |
| 10922 | auto irb = mBfIRBuilder; |
| 10923 | |
| 10924 | auto checkBB = irb->CreateBlock("as.check"); |
| 10925 | auto isNull = irb->CreateIsNull(targetValue.mValue); |
| 10926 | mBfIRBuilder->CreateCondBr(isNull, nullSucceeds ? trueBlock : falseBlock, checkBB); |
| 10927 | |
| 10928 | if (mIsComptimeModule) |
| 10929 | { |
| 10930 | AddBasicBlock(checkBB); |
| 10931 | auto callResult = mBfIRBuilder->Comptime_DynamicCastCheck(targetValue.mValue, targetType->mTypeId, mBfIRBuilder->MapType(mContext->mBfObjectType)); |
| 10932 | auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult, GetDefaultValue(mContext->mBfObjectType)); |
| 10933 | irb->CreateCondBr(cmpResult, trueBlock, falseBlock); |
| 10934 | return; |
| 10935 | } |
| 10936 | |
| 10937 | auto intType = GetPrimitiveType(BfTypeCode_IntPtr); |
| 10938 | auto intPtrType = CreatePointerType(intType); |
| 10939 | auto intPtrPtrType = CreatePointerType(intPtrType); |
| 10940 | auto int32Type = GetPrimitiveType(BfTypeCode_Int32); |
| 10941 | auto int32PtrType = CreatePointerType(int32Type); |
| 10942 | |
| 10943 | auto typeTypeInstance = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef)->ToTypeInstance(); |
| 10944 | |
| 10945 | if (mCompiler->mOptions.mAllowHotSwapping) |
| 10946 | { |
| 10947 | BfExprEvaluator exprEvaluator(this); |
| 10948 | |
| 10949 | AddBasicBlock(checkBB); |
| 10950 | auto objectParam = mBfIRBuilder->CreateBitCast(targetValue.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType)); |
| 10951 | auto moduleMethodInstance = GetMethodByName(mContext->mBfObjectType, targetType->IsInterface() ? "DynamicCastToInterface" : "DynamicCastToTypeId"); |
| 10952 | SizedArray<BfIRValue, 4> irArgs; |
| 10953 | irArgs.push_back(objectParam); |
| 10954 | irArgs.push_back(GetConstValue32(targetType->mTypeId)); |
| 10955 | auto callResult = exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs); |
| 10956 | auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult.mValue, GetDefaultValue(callResult.mType)); |
| 10957 | irb->CreateCondBr(cmpResult, trueBlock, falseBlock); |
| 10958 | } |
| 10959 | else |
| 10960 | { |
| 10961 | AddBasicBlock(checkBB); |
| 10962 | BfIRValue vDataPtr = irb->CreateBitCast(targetValue.mValue, irb->MapType(intPtrType)); |
| 10963 | vDataPtr = irb->CreateLoad(vDataPtr); |
| 10964 | if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) |
| 10965 | vDataPtr = irb->CreateAnd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL)); |
| 10966 | |
| 10967 | if (targetType->IsInterface()) |
| 10968 | { |
| 10969 | auto targetTypeInst = targetType->ToTypeInstance(); |
| 10970 | AddDependency(targetType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); |
| 10971 | |
| 10972 | // Skip past mType, but since a 'GetDynCastVDataCount()' data is included in the sSlotOfs, we need to remove that |
| 10973 | //int inheritanceIdOfs = mSystem->mPtrSize - (mCompiler->GetDynCastVDataCount())*4; |
| 10974 | //vDataPtr = irb->CreateAdd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, inheritanceIdOfs)); |
no test coverage detected