1 //===-- c_api_test.cpp ----------------------------------------------------===//
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 // This file is a part of the ORC runtime.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "orc_rt/c_api.h"
14 #include "gtest/gtest.h"
15
TEST(CAPITest,CWrapperFunctionResultInit)16 TEST(CAPITest, CWrapperFunctionResultInit) {
17 orc_rt_CWrapperFunctionResult R;
18 orc_rt_CWrapperFunctionResultInit(&R);
19
20 EXPECT_EQ(R.Size, 0U);
21 EXPECT_EQ(R.Data.ValuePtr, nullptr);
22
23 // Check that this value isn't treated as an out-of-band error.
24 EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
25
26 // Check that we can dispose of the value.
27 orc_rt_DisposeCWrapperFunctionResult(&R);
28 }
29
TEST(CAPITest,CWrapperFunctionResultAllocSmall)30 TEST(CAPITest, CWrapperFunctionResultAllocSmall) {
31 constexpr size_t SmallAllocSize = sizeof(const char *);
32
33 auto R = orc_rt_CWrapperFunctionResultAllocate(SmallAllocSize);
34 char *DataPtr = orc_rt_CWrapperFunctionResultData(&R);
35
36 for (size_t I = 0; I != SmallAllocSize; ++I)
37 DataPtr[I] = 0x55 + I;
38
39 // Check that the inline storage in R.Data.Value contains the expected
40 // sequence.
41 EXPECT_EQ(R.Size, SmallAllocSize);
42 for (size_t I = 0; I != SmallAllocSize; ++I)
43 EXPECT_EQ(R.Data.Value[I], (char)(0x55 + I))
44 << "Unexpected value at index " << I;
45
46 // Check that this value isn't treated as an out-of-band error.
47 EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
48
49 // Check that orc_rt_CWrapperFunctionResult(Data|Result|Size) and
50 // orc_rt_CWrapperFunctionResultGetOutOfBandError behave as expected.
51 EXPECT_EQ(orc_rt_CWrapperFunctionResultData(&R), R.Data.Value);
52 EXPECT_EQ(orc_rt_CWrapperFunctionResultSize(&R), SmallAllocSize);
53 EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(&R));
54 EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
55
56 // Check that we can dispose of the value.
57 orc_rt_DisposeCWrapperFunctionResult(&R);
58 }
59
TEST(CAPITest,CWrapperFunctionResultAllocLarge)60 TEST(CAPITest, CWrapperFunctionResultAllocLarge) {
61 constexpr size_t LargeAllocSize = sizeof(const char *) + 1;
62
63 auto R = orc_rt_CWrapperFunctionResultAllocate(LargeAllocSize);
64 char *DataPtr = orc_rt_CWrapperFunctionResultData(&R);
65
66 for (size_t I = 0; I != LargeAllocSize; ++I)
67 DataPtr[I] = 0x55 + I;
68
69 // Check that the inline storage in R.Data.Value contains the expected
70 // sequence.
71 EXPECT_EQ(R.Size, LargeAllocSize);
72 EXPECT_EQ(R.Data.ValuePtr, DataPtr);
73 for (size_t I = 0; I != LargeAllocSize; ++I)
74 EXPECT_EQ(R.Data.ValuePtr[I], (char)(0x55 + I))
75 << "Unexpected value at index " << I;
76
77 // Check that this value isn't treated as an out-of-band error.
78 EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
79
80 // Check that orc_rt_CWrapperFunctionResult(Data|Result|Size) and
81 // orc_rt_CWrapperFunctionResultGetOutOfBandError behave as expected.
82 EXPECT_EQ(orc_rt_CWrapperFunctionResultData(&R), R.Data.ValuePtr);
83 EXPECT_EQ(orc_rt_CWrapperFunctionResultSize(&R), LargeAllocSize);
84 EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(&R));
85 EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
86
87 // Check that we can dispose of the value.
88 orc_rt_DisposeCWrapperFunctionResult(&R);
89 }
90
TEST(CAPITest,CWrapperFunctionResultFromRangeSmall)91 TEST(CAPITest, CWrapperFunctionResultFromRangeSmall) {
92 constexpr size_t SmallAllocSize = sizeof(const char *);
93
94 char Source[SmallAllocSize];
95 for (size_t I = 0; I != SmallAllocSize; ++I)
96 Source[I] = 0x55 + I;
97
98 orc_rt_CWrapperFunctionResult R =
99 orc_rt_CreateCWrapperFunctionResultFromRange(Source, SmallAllocSize);
100
101 // Check that the inline storage in R.Data.Value contains the expected
102 // sequence.
103 EXPECT_EQ(R.Size, SmallAllocSize);
104 for (size_t I = 0; I != SmallAllocSize; ++I)
105 EXPECT_EQ(R.Data.Value[I], (char)(0x55 + I))
106 << "Unexpected value at index " << I;
107
108 // Check that we can dispose of the value.
109 orc_rt_DisposeCWrapperFunctionResult(&R);
110 }
111
TEST(CAPITest,CWrapperFunctionResultFromRangeLarge)112 TEST(CAPITest, CWrapperFunctionResultFromRangeLarge) {
113 constexpr size_t LargeAllocSize = sizeof(const char *) + 1;
114
115 char Source[LargeAllocSize];
116 for (size_t I = 0; I != LargeAllocSize; ++I)
117 Source[I] = 0x55 + I;
118
119 orc_rt_CWrapperFunctionResult R =
120 orc_rt_CreateCWrapperFunctionResultFromRange(Source, LargeAllocSize);
121
122 // Check that the inline storage in R.Data.Value contains the expected
123 // sequence.
124 EXPECT_EQ(R.Size, LargeAllocSize);
125 for (size_t I = 0; I != LargeAllocSize; ++I)
126 EXPECT_EQ(R.Data.ValuePtr[I], (char)(0x55 + I))
127 << "Unexpected value at index " << I;
128
129 // Check that we can dispose of the value.
130 orc_rt_DisposeCWrapperFunctionResult(&R);
131 }
132
TEST(CAPITest,CWrapperFunctionResultFromStringSmall)133 TEST(CAPITest, CWrapperFunctionResultFromStringSmall) {
134 constexpr size_t SmallAllocSize = sizeof(const char *);
135
136 char Source[SmallAllocSize];
137 for (size_t I = 0; I != SmallAllocSize - 1; ++I)
138 Source[I] = 'a' + I;
139 Source[SmallAllocSize - 1] = '\0';
140
141 orc_rt_CWrapperFunctionResult R =
142 orc_rt_CreateCWrapperFunctionResultFromString(Source);
143
144 // Check that the inline storage in R.Data.Value contains the expected
145 // sequence.
146 EXPECT_EQ(R.Size, SmallAllocSize);
147 for (size_t I = 0; I != SmallAllocSize - 1; ++I)
148 EXPECT_EQ(R.Data.Value[I], (char)('a' + I))
149 << "Unexpected value at index " << I;
150 EXPECT_EQ(R.Data.Value[SmallAllocSize - 1], '\0')
151 << "Unexpected value at index " << (SmallAllocSize - 1);
152
153 // Check that we can dispose of the value.
154 orc_rt_DisposeCWrapperFunctionResult(&R);
155 }
156
TEST(CAPITest,CWrapperFunctionResultFromStringLarge)157 TEST(CAPITest, CWrapperFunctionResultFromStringLarge) {
158 constexpr size_t LargeAllocSize = sizeof(const char *) + 1;
159
160 char Source[LargeAllocSize];
161 for (size_t I = 0; I != LargeAllocSize - 1; ++I)
162 Source[I] = 'a' + I;
163 Source[LargeAllocSize - 1] = '\0';
164
165 orc_rt_CWrapperFunctionResult R =
166 orc_rt_CreateCWrapperFunctionResultFromString(Source);
167
168 // Check that the inline storage in R.Data.Value contains the expected
169 // sequence.
170 EXPECT_EQ(R.Size, LargeAllocSize);
171 for (size_t I = 0; I != LargeAllocSize - 1; ++I)
172 EXPECT_EQ(R.Data.ValuePtr[I], (char)('a' + I))
173 << "Unexpected value at index " << I;
174 EXPECT_EQ(R.Data.ValuePtr[LargeAllocSize - 1], '\0')
175 << "Unexpected value at index " << (LargeAllocSize - 1);
176
177 // Check that we can dispose of the value.
178 orc_rt_DisposeCWrapperFunctionResult(&R);
179 }
180
TEST(CAPITest,CWrapperFunctionResultFromOutOfBandError)181 TEST(CAPITest, CWrapperFunctionResultFromOutOfBandError) {
182 constexpr const char *ErrMsg = "test error message";
183 orc_rt_CWrapperFunctionResult R =
184 orc_rt_CreateCWrapperFunctionResultFromOutOfBandError(ErrMsg);
185
186 #ifndef NDEBUG
187 EXPECT_DEATH({ orc_rt_CWrapperFunctionResultData(&R); },
188 "Cannot get data for out-of-band error value");
189 EXPECT_DEATH({ orc_rt_CWrapperFunctionResultSize(&R); },
190 "Cannot get size for out-of-band error value");
191 #endif
192
193 EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(&R));
194 const char *OOBErrMsg = orc_rt_CWrapperFunctionResultGetOutOfBandError(&R);
195 EXPECT_NE(OOBErrMsg, nullptr);
196 EXPECT_NE(OOBErrMsg, ErrMsg);
197 EXPECT_TRUE(strcmp(OOBErrMsg, ErrMsg) == 0);
198
199 orc_rt_DisposeCWrapperFunctionResult(&R);
200 }
201