| 4472 | } |
| 4473 | |
| 4474 | void compileCallRefOp(const unsigned int TypeIndex) noexcept { |
| 4475 | auto NotNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_r.not_null"); |
| 4476 | auto IsNullBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_r.is_null"); |
| 4477 | auto EndBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_i.end"); |
| 4478 | |
| 4479 | auto Ref = Builder.createBitCast(stackPop(), Context.Int64x2Ty); |
| 4480 | auto OkBB = LLVM::BasicBlock::create(LLContext, F.Fn, "c_r.ref_not_null"); |
| 4481 | auto IsRefNotNull = Builder.createLikely(Builder.createICmpNE( |
| 4482 | Builder.createExtractElement(Ref, LLContext.getInt64(1)), |
| 4483 | LLContext.getInt64(0))); |
| 4484 | Builder.createCondBr(IsRefNotNull, OkBB, |
| 4485 | getTrapBB(ErrCode::Value::AccessNullFunc)); |
| 4486 | Builder.positionAtEnd(OkBB); |
| 4487 | |
| 4488 | const auto &FuncType = Context.CompositeTypes[TypeIndex]->getFuncType(); |
| 4489 | auto FTy = toLLVMType(Context.LLContext, Context.ExecCtxPtrTy, FuncType); |
| 4490 | auto RTy = FTy.getReturnType(); |
| 4491 | |
| 4492 | const size_t ArgSize = FuncType.getParamTypes().size(); |
| 4493 | const size_t RetSize = |
| 4494 | RTy.isVoidTy() ? 0 : FuncType.getReturnTypes().size(); |
| 4495 | std::vector<LLVM::Value> ArgsVec(ArgSize + 1, nullptr); |
| 4496 | ArgsVec[0] = F.Fn.getFirstParam(); |
| 4497 | for (size_t I = 0; I < ArgSize; ++I) { |
| 4498 | const size_t J = ArgSize - I; |
| 4499 | ArgsVec[J] = stackPop(); |
| 4500 | } |
| 4501 | |
| 4502 | std::vector<LLVM::Value> FPtrRetsVec; |
| 4503 | FPtrRetsVec.reserve(RetSize); |
| 4504 | { |
| 4505 | auto FPtr = Builder.createCall( |
| 4506 | Context.getIntrinsic( |
| 4507 | Builder, Executable::Intrinsics::kRefGetFuncSymbol, |
| 4508 | LLVM::Type::getFunctionType(FTy.getPointerTo(), |
| 4509 | {Context.Int64x2Ty}, false)), |
| 4510 | {Ref}); |
| 4511 | Builder.createCondBr( |
| 4512 | Builder.createLikely(Builder.createNot(Builder.createIsNull(FPtr))), |
| 4513 | NotNullBB, IsNullBB); |
| 4514 | Builder.positionAtEnd(NotNullBB); |
| 4515 | |
| 4516 | auto FPtrRet = |
| 4517 | Builder.createCall(LLVM::FunctionCallee{FTy, FPtr}, ArgsVec); |
| 4518 | if (RetSize == 0) { |
| 4519 | // nothing to do |
| 4520 | } else if (RetSize == 1) { |
| 4521 | FPtrRetsVec.push_back(FPtrRet); |
| 4522 | } else { |
| 4523 | for (auto Val : unpackStruct(Builder, FPtrRet)) { |
| 4524 | FPtrRetsVec.push_back(Val); |
| 4525 | } |
| 4526 | } |
| 4527 | } |
| 4528 | |
| 4529 | Builder.createBr(EndBB); |
| 4530 | Builder.positionAtEnd(IsNullBB); |
| 4531 |
nothing calls this directly
no test coverage detected