| 4568 | } |
| 4569 | |
| 4570 | void compileReturnCallRefOp(const unsigned int TypeIndex) noexcept { |
| 4571 | auto NotNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_r.not_null"); |
| 4572 | auto IsNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_r.is_null"); |
| 4573 | |
| 4574 | auto Ref = Builder.createBitCast(stackPop(), Context.Int64x2Ty); |
| 4575 | auto OkBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_r.ref_not_null"); |
| 4576 | auto IsRefNotNull = Builder.createLikely(Builder.createICmpNE( |
| 4577 | Builder.createExtractElement(Ref, LLContext.getInt64(1)), |
| 4578 | LLContext.getInt64(0))); |
| 4579 | Builder.createCondBr(IsRefNotNull, OkBB, |
| 4580 | getTrapBB(ErrCode::Value::AccessNullFunc)); |
| 4581 | Builder.positionAtEnd(OkBB); |
| 4582 | |
| 4583 | const auto &FuncType = Context.CompositeTypes[TypeIndex]->getFuncType(); |
| 4584 | auto FTy = toLLVMType(Context.LLContext, Context.ExecCtxPtrTy, FuncType); |
| 4585 | auto RTy = FTy.getReturnType(); |
| 4586 | |
| 4587 | const size_t ArgSize = FuncType.getParamTypes().size(); |
| 4588 | const size_t RetSize = |
| 4589 | RTy.isVoidTy() ? 0 : FuncType.getReturnTypes().size(); |
| 4590 | std::vector<LLVM::Value> ArgsVec(ArgSize + 1, nullptr); |
| 4591 | ArgsVec[0] = F.Fn.getFirstParam(); |
| 4592 | for (size_t I = 0; I < ArgSize; ++I) { |
| 4593 | const size_t J = ArgSize - I; |
| 4594 | ArgsVec[J] = stackPop(); |
| 4595 | } |
| 4596 | |
| 4597 | { |
| 4598 | auto FPtr = Builder.createCall( |
| 4599 | Context.getIntrinsic( |
| 4600 | Builder, Executable::Intrinsics::kRefGetFuncSymbol, |
| 4601 | LLVM::Type::getFunctionType(FTy.getPointerTo(), |
| 4602 | {Context.Int64x2Ty}, false)), |
| 4603 | {Ref}); |
| 4604 | Builder.createCondBr( |
| 4605 | Builder.createLikely(Builder.createNot(Builder.createIsNull(FPtr))), |
| 4606 | NotNullBB, IsNullBB); |
| 4607 | Builder.positionAtEnd(NotNullBB); |
| 4608 | |
| 4609 | auto FPtrRet = |
| 4610 | Builder.createCall(LLVM::FunctionCallee(FTy, FPtr), ArgsVec); |
| 4611 | if (RetSize == 0) { |
| 4612 | Builder.createRetVoid(); |
| 4613 | } else { |
| 4614 | Builder.createRet(FPtrRet); |
| 4615 | } |
| 4616 | } |
| 4617 | |
| 4618 | Builder.positionAtEnd(IsNullBB); |
| 4619 | |
| 4620 | { |
| 4621 | LLVM::Value Args = Builder.createArray(ArgSize, kValSize); |
| 4622 | LLVM::Value Rets = Builder.createArray(RetSize, kValSize); |
| 4623 | Builder.createArrayPtrStore( |
| 4624 | Span<LLVM::Value>(ArgsVec.begin() + 1, ArgSize), Args, Context.Int8Ty, |
| 4625 | kValSize); |
| 4626 | |
| 4627 | Builder.createCall( |
nothing calls this directly
no test coverage detected