xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp (revision a01f772d19d53976a6d6e0eed684440e4f2cc9da)
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