| 4281 | } |
| 4282 | |
| 4283 | void compileIndirectCallOp(const uint32_t TableIndex, |
| 4284 | const uint32_t FuncTypeIndex) noexcept { |
| 4285 | auto NotNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_i.not_null"); |
| 4286 | auto IsNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_i.is_null"); |
| 4287 | auto EndBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_i.end"); |
| 4288 | |
| 4289 | LLVM::Value FuncIndex = stackPop(); |
| 4290 | const auto &FuncType = Context.CompositeTypes[FuncTypeIndex]->getFuncType(); |
| 4291 | auto FTy = toLLVMType(Context.LLContext, Context.ExecCtxPtrTy, FuncType); |
| 4292 | auto RTy = FTy.getReturnType(); |
| 4293 | |
| 4294 | const size_t ArgSize = FuncType.getParamTypes().size(); |
| 4295 | const size_t RetSize = |
| 4296 | RTy.isVoidTy() ? 0 : FuncType.getReturnTypes().size(); |
| 4297 | std::vector<LLVM::Value> ArgsVec(ArgSize + 1, nullptr); |
| 4298 | ArgsVec[0] = F.Fn.getFirstParam(); |
| 4299 | for (size_t I = 0; I < ArgSize; ++I) { |
| 4300 | const size_t J = ArgSize - I; |
| 4301 | ArgsVec[J] = stackPop(); |
| 4302 | } |
| 4303 | |
| 4304 | std::vector<LLVM::Value> FPtrRetsVec; |
| 4305 | FPtrRetsVec.reserve(RetSize); |
| 4306 | { |
| 4307 | auto FPtr = Builder.createCall( |
| 4308 | Context.getIntrinsic( |
| 4309 | Builder, Executable::Intrinsics::kTableGetFuncSymbol, |
| 4310 | LLVM::Type::getFunctionType( |
| 4311 | FTy.getPointerTo(), |
| 4312 | {Context.Int32Ty, Context.Int32Ty, Context.Int32Ty}, false)), |
| 4313 | {LLContext.getInt32(TableIndex), LLContext.getInt32(FuncTypeIndex), |
| 4314 | FuncIndex}); |
| 4315 | Builder.createCondBr( |
| 4316 | Builder.createLikely(Builder.createNot(Builder.createIsNull(FPtr))), |
| 4317 | NotNullBB, IsNullBB); |
| 4318 | Builder.positionAtEnd(NotNullBB); |
| 4319 | |
| 4320 | auto FPtrRet = |
| 4321 | Builder.createCall(LLVM::FunctionCallee{FTy, FPtr}, ArgsVec); |
| 4322 | if (RetSize == 0) { |
| 4323 | // nothing to do |
| 4324 | } else if (RetSize == 1) { |
| 4325 | FPtrRetsVec.push_back(FPtrRet); |
| 4326 | } else { |
| 4327 | for (auto Val : unpackStruct(Builder, FPtrRet)) { |
| 4328 | FPtrRetsVec.push_back(Val); |
| 4329 | } |
| 4330 | } |
| 4331 | } |
| 4332 | |
| 4333 | Builder.createBr(EndBB); |
| 4334 | Builder.positionAtEnd(IsNullBB); |
| 4335 | |
| 4336 | std::vector<LLVM::Value> RetsVec; |
| 4337 | { |
| 4338 | LLVM::Value Args = Builder.createArray(ArgSize, kValSize); |
| 4339 | LLVM::Value Rets = Builder.createArray(RetSize, kValSize); |
| 4340 | Builder.createArrayPtrStore( |
nothing calls this directly
no test coverage detected