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(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 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(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 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 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 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 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