//===----------- CallSPSViaEPC.cpp - Test CallSPSViaEPC.h APIs ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/CallSPSViaEPC.h" #include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h" #include "llvm/Testing/Support/Error.h" #include #include "gtest/gtest.h" using namespace llvm; using namespace llvm::orc; using namespace llvm::orc::shared; static CWrapperFunctionBuffer voidWrapper(const char *ArgData, size_t ArgSize) { return WrapperFunction::handle(ArgData, ArgSize, []() {}).release(); } static CWrapperFunctionBuffer mainWrapper(const char *ArgData, size_t ArgSize) { return WrapperFunction)>::handle( ArgData, ArgSize, [](std::vector Args) -> int32_t { return Args.size(); }) .release(); } TEST(CallSPSViaEPCTest, CallVoidViaCallerAsync) { auto EPC = cantFail(SelfExecutorProcessControl::Create()); SPSEPCCaller C(*EPC); Error Err = Error::success(); { ErrorAsOutParameter _(Err); C([&](Error E) { Err = std::move(E); }, ExecutorSymbolDef::fromPtr(voidWrapper)); } EXPECT_THAT_ERROR(std::move(Err), Succeeded()); } TEST(CallSPSViaEPCTest, CallVoidViaCallerSync) { auto EPC = cantFail(SelfExecutorProcessControl::Create()); SPSEPCCaller C(*EPC); Error Err = C(std::promise(), ExecutorSymbolDef::fromPtr(voidWrapper)); EXPECT_THAT_ERROR(std::move(Err), Succeeded()); } TEST(CallSPSViaEPCTest, CallMainViaCallerAsync) { auto EPC = cantFail(SelfExecutorProcessControl::Create()); SPSEPCCaller)> C(*EPC); std::vector Args; std::optional> R1; C([&](Expected R) { R1 = std::move(R); }, ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(*R1, Succeeded()); EXPECT_EQ(**R1, 0); Args.push_back("foo"); std::optional> R2; C([&](Expected R) { R2 = std::move(R); }, ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(*R2, Succeeded()); EXPECT_EQ(**R2, 1); Args.push_back("foo"); std::optional> R3; C([&](Expected R) { R3 = std::move(R); }, ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(*R3, Succeeded()); EXPECT_EQ(**R3, 2); Args.clear(); std::optional> R4; C([&](Expected R) { R4 = std::move(R); }, ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(*R4, Succeeded()); EXPECT_EQ(**R4, 0); } TEST(CallSPSViaEPCTest, CallMainViaGenericCallAsync) { auto EPC = cantFail(SelfExecutorProcessControl::Create()); SPSEPCCall)> C( *EPC, ExecutorSymbolDef::fromPtr(mainWrapper)); std::vector Args; std::optional> R1; C([&](Expected R) { R1 = std::move(R); }, Args); ASSERT_THAT_EXPECTED(*R1, Succeeded()); EXPECT_EQ(**R1, 0); Args.push_back("foo"); std::optional> R2; C([&](Expected R) { R2 = std::move(R); }, Args); ASSERT_THAT_EXPECTED(*R2, Succeeded()); EXPECT_EQ(**R2, 1); Args.push_back("foo"); std::optional> R3; C([&](Expected R) { R3 = std::move(R); }, Args); ASSERT_THAT_EXPECTED(*R3, Succeeded()); EXPECT_EQ(**R3, 2); Args.clear(); std::optional> R4; C([&](Expected R) { R4 = std::move(R); }, Args); ASSERT_THAT_EXPECTED(*R4, Succeeded()); EXPECT_EQ(**R4, 0); } TEST(CallSPSViaEPCTest, CallMainViaCallerSync) { auto EPC = cantFail(SelfExecutorProcessControl::Create()); SPSEPCCaller)> C(*EPC); std::vector Args; Expected R1 = C(std::promise>(), ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(R1, Succeeded()); EXPECT_EQ(*R1, 0); Args.push_back("foo"); Expected R2 = C(std::promise>(), ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(R2, Succeeded()); EXPECT_EQ(*R2, 1); Args.push_back("foo"); Expected R3 = C(std::promise>(), ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(R3, Succeeded()); EXPECT_EQ(*R3, 2); Args.clear(); Expected R4 = C(std::promise>(), ExecutorSymbolDef::fromPtr(mainWrapper), Args); ASSERT_THAT_EXPECTED(R4, Succeeded()); EXPECT_EQ(*R4, 0); } TEST(CallSPSViaEPCTest, CallMainViaGenericCallSync) { auto EPC = cantFail(SelfExecutorProcessControl::Create()); SPSEPCCall)> C( *EPC, ExecutorSymbolDef::fromPtr(mainWrapper)); std::vector Args; Expected R1 = C(std::promise>(), Args); ASSERT_THAT_EXPECTED(R1, Succeeded()); EXPECT_EQ(*R1, 0); Args.push_back("foo"); Expected R2 = C(std::promise>(), Args); ASSERT_THAT_EXPECTED(R2, Succeeded()); EXPECT_EQ(*R2, 1); Args.push_back("foo"); Expected R3 = C(std::promise>(), Args); ASSERT_THAT_EXPECTED(R3, Succeeded()); EXPECT_EQ(*R3, 2); Args.clear(); Expected R4 = C(std::promise>(), Args); ASSERT_THAT_EXPECTED(R4, Succeeded()); EXPECT_EQ(*R4, 0); }