Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/include/orc_rt/c_api.h
35233 views
1
/*===- c_api.h - C API for the ORC runtime ------------------------*- C -*-===*\
2
|* *|
3
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
4
|* Exceptions. *|
5
|* See https://llvm.org/LICENSE.txt for license information. *|
6
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
7
|* *|
8
|*===----------------------------------------------------------------------===*|
9
|* *|
10
|* This file defines the C API for the ORC runtime *|
11
|* *|
12
\*===----------------------------------------------------------------------===*/
13
14
#ifndef ORC_RT_C_API_H
15
#define ORC_RT_C_API_H
16
17
#include <assert.h>
18
#include <stdio.h>
19
#include <stdlib.h>
20
#include <string.h>
21
22
/* Helper to suppress strict prototype warnings. */
23
#ifdef __clang__
24
#define ORC_RT_C_STRICT_PROTOTYPES_BEGIN \
25
_Pragma("clang diagnostic push") \
26
_Pragma("clang diagnostic error \"-Wstrict-prototypes\"")
27
#define ORC_RT_C_STRICT_PROTOTYPES_END _Pragma("clang diagnostic pop")
28
#else
29
#define ORC_RT_C_STRICT_PROTOTYPES_BEGIN
30
#define ORC_RT_C_STRICT_PROTOTYPES_END
31
#endif
32
33
/* Helper to wrap C code for C++ */
34
#ifdef __cplusplus
35
#define ORC_RT_C_EXTERN_C_BEGIN \
36
extern "C" { \
37
ORC_RT_C_STRICT_PROTOTYPES_BEGIN
38
#define ORC_RT_C_EXTERN_C_END \
39
ORC_RT_C_STRICT_PROTOTYPES_END \
40
}
41
#else
42
#define ORC_RT_C_EXTERN_C_BEGIN ORC_RT_C_STRICT_PROTOTYPES_BEGIN
43
#define ORC_RT_C_EXTERN_C_END ORC_RT_C_STRICT_PROTOTYPES_END
44
#endif
45
46
ORC_RT_C_EXTERN_C_BEGIN
47
48
typedef union {
49
char *ValuePtr;
50
char Value[sizeof(char *)];
51
} orc_rt_CWrapperFunctionResultDataUnion;
52
53
/**
54
* orc_rt_CWrapperFunctionResult is a kind of C-SmallVector with an
55
* out-of-band error state.
56
*
57
* If Size == 0 and Data.ValuePtr is non-zero then the value is in the
58
* 'out-of-band error' state, and Data.ValuePtr points at a malloc-allocated,
59
* null-terminated string error message.
60
*
61
* If Size <= sizeof(orc_rt_CWrapperFunctionResultData) then the value is in
62
* the 'small' state and the content is held in the first Size bytes of
63
* Data.Value.
64
*
65
* If Size > sizeof(OrtRTCWrapperFunctionResultData) then the value is in the
66
* 'large' state and the content is held in the first Size bytes of the
67
* memory pointed to by Data.ValuePtr. This memory must have been allocated by
68
* malloc, and will be freed with free when this value is destroyed.
69
*/
70
typedef struct {
71
orc_rt_CWrapperFunctionResultDataUnion Data;
72
size_t Size;
73
} orc_rt_CWrapperFunctionResult;
74
75
/**
76
* Zero-initialize an orc_rt_CWrapperFunctionResult.
77
*/
78
static inline void
79
orc_rt_CWrapperFunctionResultInit(orc_rt_CWrapperFunctionResult *R) {
80
R->Size = 0;
81
R->Data.ValuePtr = 0;
82
}
83
84
/**
85
* Create an orc_rt_CWrapperFunctionResult with an uninitialized buffer of
86
* size Size. The buffer is returned via the DataPtr argument.
87
*/
88
static inline orc_rt_CWrapperFunctionResult
89
orc_rt_CWrapperFunctionResultAllocate(size_t Size) {
90
orc_rt_CWrapperFunctionResult R;
91
R.Size = Size;
92
// If Size is 0 ValuePtr must be 0 or it is considered an out-of-band error.
93
R.Data.ValuePtr = 0;
94
if (Size > sizeof(R.Data.Value))
95
R.Data.ValuePtr = (char *)malloc(Size);
96
return R;
97
}
98
99
/**
100
* Create an orc_rt_WrapperFunctionResult from the given data range.
101
*/
102
static inline orc_rt_CWrapperFunctionResult
103
orc_rt_CreateCWrapperFunctionResultFromRange(const char *Data, size_t Size) {
104
orc_rt_CWrapperFunctionResult R;
105
R.Size = Size;
106
if (R.Size > sizeof(R.Data.Value)) {
107
char *Tmp = (char *)malloc(Size);
108
memcpy(Tmp, Data, Size);
109
R.Data.ValuePtr = Tmp;
110
} else
111
memcpy(R.Data.Value, Data, Size);
112
return R;
113
}
114
115
/**
116
* Create an orc_rt_CWrapperFunctionResult by copying the given string,
117
* including the null-terminator.
118
*
119
* This function copies the input string. The client is responsible for freeing
120
* the ErrMsg arg.
121
*/
122
static inline orc_rt_CWrapperFunctionResult
123
orc_rt_CreateCWrapperFunctionResultFromString(const char *Source) {
124
return orc_rt_CreateCWrapperFunctionResultFromRange(Source,
125
strlen(Source) + 1);
126
}
127
128
/**
129
* Create an orc_rt_CWrapperFunctionResult representing an out-of-band
130
* error.
131
*
132
* This function copies the input string. The client is responsible for freeing
133
* the ErrMsg arg.
134
*/
135
static inline orc_rt_CWrapperFunctionResult
136
orc_rt_CreateCWrapperFunctionResultFromOutOfBandError(const char *ErrMsg) {
137
orc_rt_CWrapperFunctionResult R;
138
R.Size = 0;
139
char *Tmp = (char *)malloc(strlen(ErrMsg) + 1);
140
strcpy(Tmp, ErrMsg);
141
R.Data.ValuePtr = Tmp;
142
return R;
143
}
144
145
/**
146
* This should be called to destroy orc_rt_CWrapperFunctionResult values
147
* regardless of their state.
148
*/
149
static inline void
150
orc_rt_DisposeCWrapperFunctionResult(orc_rt_CWrapperFunctionResult *R) {
151
if (R->Size > sizeof(R->Data.Value) ||
152
(R->Size == 0 && R->Data.ValuePtr))
153
free(R->Data.ValuePtr);
154
}
155
156
/**
157
* Get a pointer to the data contained in the given
158
* orc_rt_CWrapperFunctionResult.
159
*/
160
static inline char *
161
orc_rt_CWrapperFunctionResultData(orc_rt_CWrapperFunctionResult *R) {
162
assert((R->Size != 0 || R->Data.ValuePtr == NULL) &&
163
"Cannot get data for out-of-band error value");
164
return R->Size > sizeof(R->Data.Value) ? R->Data.ValuePtr : R->Data.Value;
165
}
166
167
/**
168
* Safely get the size of the given orc_rt_CWrapperFunctionResult.
169
*
170
* Asserts that we're not trying to access the size of an error value.
171
*/
172
static inline size_t
173
orc_rt_CWrapperFunctionResultSize(const orc_rt_CWrapperFunctionResult *R) {
174
assert((R->Size != 0 || R->Data.ValuePtr == NULL) &&
175
"Cannot get size for out-of-band error value");
176
return R->Size;
177
}
178
179
/**
180
* Returns 1 if this value is equivalent to a value just initialized by
181
* orc_rt_CWrapperFunctionResultInit, 0 otherwise.
182
*/
183
static inline size_t
184
orc_rt_CWrapperFunctionResultEmpty(const orc_rt_CWrapperFunctionResult *R) {
185
return R->Size == 0 && R->Data.ValuePtr == 0;
186
}
187
188
/**
189
* Returns a pointer to the out-of-band error string for this
190
* orc_rt_CWrapperFunctionResult, or null if there is no error.
191
*
192
* The orc_rt_CWrapperFunctionResult retains ownership of the error
193
* string, so it should be copied if the caller wishes to preserve it.
194
*/
195
static inline const char *orc_rt_CWrapperFunctionResultGetOutOfBandError(
196
const orc_rt_CWrapperFunctionResult *R) {
197
return R->Size == 0 ? R->Data.ValuePtr : 0;
198
}
199
200
ORC_RT_C_EXTERN_C_END
201
202
#endif /* ORC_RT_C_API_H */
203
204