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 | |
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 | |
30 | TEST(CAPITest, CWrapperFunctionResultAllocSmall) { |
31 | constexpr size_t SmallAllocSize = sizeof(const char *); |
32 | |
33 | auto R = orc_rt_CWrapperFunctionResultAllocate(Size: SmallAllocSize); |
34 | char *DataPtr = orc_rt_CWrapperFunctionResultData(R: &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: &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), R.Data.Value); |
52 | EXPECT_EQ(orc_rt_CWrapperFunctionResultSize(R: &R), SmallAllocSize); |
53 | EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(R: &R)); |
54 | EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(R: &R), nullptr); |
55 | |
56 | // Check that we can dispose of the value. |
57 | orc_rt_DisposeCWrapperFunctionResult(R: &R); |
58 | } |
59 | |
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 | |
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(Data: Source, Size: 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: &R); |
110 | } |
111 | |
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(Data: Source, Size: 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: &R); |
131 | } |
132 | |
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: &R); |
155 | } |
156 | |
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: &R); |
179 | } |
180 | |
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 | |