| 4397 | } |
| 4398 | |
| 4399 | void compileReturnIndirectCallOp(const uint32_t TableIndex, |
| 4400 | const uint32_t FuncTypeIndex) noexcept { |
| 4401 | auto NotNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_i.not_null"); |
| 4402 | auto IsNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_i.is_null"); |
| 4403 | |
| 4404 | LLVM::Value FuncIndex = stackPop(); |
| 4405 | const auto &FuncType = Context.CompositeTypes[FuncTypeIndex]->getFuncType(); |
| 4406 | auto FTy = toLLVMType(Context.LLContext, Context.ExecCtxPtrTy, FuncType); |
| 4407 | auto RTy = FTy.getReturnType(); |
| 4408 | |
| 4409 | const size_t ArgSize = FuncType.getParamTypes().size(); |
| 4410 | const size_t RetSize = |
| 4411 | RTy.isVoidTy() ? 0 : FuncType.getReturnTypes().size(); |
| 4412 | std::vector<LLVM::Value> ArgsVec(ArgSize + 1, nullptr); |
| 4413 | ArgsVec[0] = F.Fn.getFirstParam(); |
| 4414 | for (size_t I = 0; I < ArgSize; ++I) { |
| 4415 | const size_t J = ArgSize - I; |
| 4416 | ArgsVec[J] = stackPop(); |
| 4417 | } |
| 4418 | |
| 4419 | { |
| 4420 | auto FPtr = Builder.createCall( |
| 4421 | Context.getIntrinsic( |
| 4422 | Builder, Executable::Intrinsics::kTableGetFuncSymbol, |
| 4423 | LLVM::Type::getFunctionType( |
| 4424 | FTy.getPointerTo(), |
| 4425 | {Context.Int32Ty, Context.Int32Ty, Context.Int32Ty}, false)), |
| 4426 | {LLContext.getInt32(TableIndex), LLContext.getInt32(FuncTypeIndex), |
| 4427 | FuncIndex}); |
| 4428 | Builder.createCondBr( |
| 4429 | Builder.createLikely(Builder.createNot(Builder.createIsNull(FPtr))), |
| 4430 | NotNullBB, IsNullBB); |
| 4431 | Builder.positionAtEnd(NotNullBB); |
| 4432 | |
| 4433 | auto FPtrRet = |
| 4434 | Builder.createCall(LLVM::FunctionCallee(FTy, FPtr), ArgsVec); |
| 4435 | if (RetSize == 0) { |
| 4436 | Builder.createRetVoid(); |
| 4437 | } else { |
| 4438 | Builder.createRet(FPtrRet); |
| 4439 | } |
| 4440 | } |
| 4441 | |
| 4442 | Builder.positionAtEnd(IsNullBB); |
| 4443 | |
| 4444 | { |
| 4445 | LLVM::Value Args = Builder.createArray(ArgSize, kValSize); |
| 4446 | LLVM::Value Rets = Builder.createArray(RetSize, kValSize); |
| 4447 | Builder.createArrayPtrStore( |
| 4448 | Span<LLVM::Value>(ArgsVec.begin() + 1, ArgSize), Args, Context.Int8Ty, |
| 4449 | kValSize); |
| 4450 | |
| 4451 | Builder.createCall( |
| 4452 | Context.getIntrinsic( |
| 4453 | Builder, Executable::Intrinsics::kCallIndirect, |
| 4454 | LLVM::Type::getFunctionType(Context.VoidTy, |
| 4455 | {Context.Int32Ty, Context.Int32Ty, |
| 4456 | Context.Int32Ty, Context.Int8PtrTy, |
nothing calls this directly
no test coverage detected