1 //===----- WrapperFunctionUtilsTest.cpp - Test Wrapper-Function utils -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h" 10 #include "llvm/ADT/FunctionExtras.h" 11 #include "gtest/gtest.h" 12 13 #include <future> 14 15 using namespace llvm; 16 using namespace llvm::orc; 17 using namespace llvm::orc::shared; 18 19 namespace { 20 constexpr const char *TestString = "test string"; 21 } // end anonymous namespace 22 23 TEST(WrapperFunctionUtilsTest, DefaultWrapperFunctionResult) { 24 WrapperFunctionResult R; 25 EXPECT_TRUE(R.empty()); 26 EXPECT_EQ(R.size(), 0U); 27 EXPECT_EQ(R.getOutOfBandError(), nullptr); 28 } 29 30 TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromRange) { 31 auto R = WrapperFunctionResult::copyFrom(TestString, strlen(TestString) + 1); 32 EXPECT_EQ(R.size(), strlen(TestString) + 1); 33 EXPECT_TRUE(strcmp(R.data(), TestString) == 0); 34 EXPECT_FALSE(R.empty()); 35 EXPECT_EQ(R.getOutOfBandError(), nullptr); 36 } 37 38 TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromCString) { 39 auto R = WrapperFunctionResult::copyFrom(TestString); 40 EXPECT_EQ(R.size(), strlen(TestString) + 1); 41 EXPECT_TRUE(strcmp(R.data(), TestString) == 0); 42 EXPECT_FALSE(R.empty()); 43 EXPECT_EQ(R.getOutOfBandError(), nullptr); 44 } 45 46 TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromStdString) { 47 auto R = WrapperFunctionResult::copyFrom(std::string(TestString)); 48 EXPECT_EQ(R.size(), strlen(TestString) + 1); 49 EXPECT_TRUE(strcmp(R.data(), TestString) == 0); 50 EXPECT_FALSE(R.empty()); 51 EXPECT_EQ(R.getOutOfBandError(), nullptr); 52 } 53 54 TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromOutOfBandError) { 55 auto R = WrapperFunctionResult::createOutOfBandError(TestString); 56 EXPECT_FALSE(R.empty()); 57 EXPECT_TRUE(strcmp(R.getOutOfBandError(), TestString) == 0); 58 } 59 60 static void voidNoop() {} 61 62 class AddClass { 63 public: 64 AddClass(int32_t X) : X(X) {} 65 int32_t addMethod(int32_t Y) { return X + Y; } 66 private: 67 int32_t X; 68 }; 69 70 static WrapperFunctionResult voidNoopWrapper(const char *ArgData, 71 size_t ArgSize) { 72 return WrapperFunction<void()>::handle(ArgData, ArgSize, voidNoop); 73 } 74 75 static WrapperFunctionResult addWrapper(const char *ArgData, size_t ArgSize) { 76 return WrapperFunction<int32_t(int32_t, int32_t)>::handle( 77 ArgData, ArgSize, [](int32_t X, int32_t Y) -> int32_t { return X + Y; }); 78 } 79 80 static WrapperFunctionResult addMethodWrapper(const char *ArgData, 81 size_t ArgSize) { 82 return WrapperFunction<int32_t(SPSExecutorAddress, int32_t)>::handle( 83 ArgData, ArgSize, makeMethodWrapperHandler(&AddClass::addMethod)); 84 } 85 86 TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleVoid) { 87 EXPECT_FALSE(!!WrapperFunction<void()>::call(voidNoopWrapper)); 88 } 89 90 TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleRet) { 91 int32_t Result; 92 EXPECT_FALSE(!!WrapperFunction<int32_t(int32_t, int32_t)>::call( 93 addWrapper, Result, 1, 2)); 94 EXPECT_EQ(Result, (int32_t)3); 95 } 96 97 TEST(WrapperFunctionUtilsTest, WrapperFunctionMethodCallAndHandleRet) { 98 int32_t Result; 99 AddClass AddObj(1); 100 EXPECT_FALSE(!!WrapperFunction<int32_t(SPSExecutorAddress, int32_t)>::call( 101 addMethodWrapper, Result, ExecutorAddress::fromPtr(&AddObj), 2)); 102 EXPECT_EQ(Result, (int32_t)3); 103 } 104 105 static void voidNoopAsync(unique_function<void(SPSEmpty)> SendResult) { 106 SendResult(SPSEmpty()); 107 } 108 109 static WrapperFunctionResult voidNoopAsyncWrapper(const char *ArgData, 110 size_t ArgSize) { 111 std::promise<WrapperFunctionResult> RP; 112 auto RF = RP.get_future(); 113 114 WrapperFunction<void()>::handleAsync( 115 ArgData, ArgSize, voidNoopAsync, 116 [&](WrapperFunctionResult R) { RP.set_value(std::move(R)); }); 117 118 return RF.get(); 119 } 120 121 static WrapperFunctionResult addAsyncWrapper(const char *ArgData, 122 size_t ArgSize) { 123 std::promise<WrapperFunctionResult> RP; 124 auto RF = RP.get_future(); 125 126 WrapperFunction<int32_t(int32_t, int32_t)>::handleAsync( 127 ArgData, ArgSize, 128 [](unique_function<void(int32_t)> SendResult, int32_t X, int32_t Y) { 129 SendResult(X + Y); 130 }, 131 [&](WrapperFunctionResult R) { RP.set_value(std::move(R)); }); 132 return RF.get(); 133 } 134 135 TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleAsyncVoid) { 136 EXPECT_FALSE(!!WrapperFunction<void()>::call(voidNoopAsyncWrapper)); 137 } 138 139 TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleAsyncRet) { 140 int32_t Result; 141 EXPECT_FALSE(!!WrapperFunction<int32_t(int32_t, int32_t)>::call( 142 addAsyncWrapper, Result, 1, 2)); 143 EXPECT_EQ(Result, (int32_t)3); 144 } 145