brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 6964ec0 Raw
203 lines · c
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_H15#define ORC_RT_C_API_H16 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#else29#define ORC_RT_C_STRICT_PROTOTYPES_BEGIN30#define ORC_RT_C_STRICT_PROTOTYPES_END31#endif32 33/* Helper to wrap C code for C++ */34#ifdef __cplusplus35#define ORC_RT_C_EXTERN_C_BEGIN                                                \36  extern "C" {                                                                 \37  ORC_RT_C_STRICT_PROTOTYPES_BEGIN38#define ORC_RT_C_EXTERN_C_END                                                  \39  ORC_RT_C_STRICT_PROTOTYPES_END                                               \40  }41#else42#define ORC_RT_C_EXTERN_C_BEGIN ORC_RT_C_STRICT_PROTOTYPES_BEGIN43#define ORC_RT_C_EXTERN_C_END ORC_RT_C_STRICT_PROTOTYPES_END44#endif45 46ORC_RT_C_EXTERN_C_BEGIN47 48typedef union {49  char *ValuePtr;50  char Value[sizeof(char *)];51} orc_rt_WrapperFunctionResultDataUnion;52 53/**54 * orc_rt_WrapperFunctionResult is a kind of C-SmallVector with an55 * out-of-band error state.56 *57 * If Size == 0 and Data.ValuePtr is non-zero then the value is in the58 * '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_WrapperFunctionResultData) then the value is in62 * the 'small' state and the content is held in the first Size bytes of63 * Data.Value.64 *65 * If Size > sizeof(orc_rt_WrapperFunctionResultData) then the value is in the66 * 'large' state and the content is held in the first Size bytes of the67 * memory pointed to by Data.ValuePtr. This memory must have been allocated by68 * malloc, and will be freed with free when this value is destroyed.69 */70typedef struct {71  orc_rt_WrapperFunctionResultDataUnion Data;72  size_t Size;73} orc_rt_WrapperFunctionResult;74 75/**76 * Zero-initialize an orc_rt_WrapperFunctionResult.77 */78static inline void79orc_rt_WrapperFunctionResultInit(orc_rt_WrapperFunctionResult *R) {80  R->Size = 0;81  R->Data.ValuePtr = 0;82}83 84/**85 * Create an orc_rt_WrapperFunctionResult with an uninitialized buffer of86 * size Size. The buffer is returned via the DataPtr argument.87 */88static inline orc_rt_WrapperFunctionResult89orc_rt_WrapperFunctionResultAllocate(size_t Size) {90  orc_rt_WrapperFunctionResult 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 */102static inline orc_rt_WrapperFunctionResult103orc_rt_CreateWrapperFunctionResultFromRange(const char *Data, size_t Size) {104  orc_rt_WrapperFunctionResult 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  } else111    memcpy(R.Data.Value, Data, Size);112  return R;113}114 115/**116 * Create an orc_rt_WrapperFunctionResult by copying the given string,117 * including the null-terminator.118 *119 * This function copies the input string. The client is responsible for freeing120 * the ErrMsg arg.121 */122static inline orc_rt_WrapperFunctionResult123orc_rt_CreateWrapperFunctionResultFromString(const char *Source) {124  return orc_rt_CreateWrapperFunctionResultFromRange(Source,125                                                     strlen(Source) + 1);126}127 128/**129 * Create an orc_rt_WrapperFunctionResult representing an out-of-band130 * error.131 *132 * This function copies the input string. The client is responsible for freeing133 * the ErrMsg arg.134 */135static inline orc_rt_WrapperFunctionResult136orc_rt_CreateWrapperFunctionResultFromOutOfBandError(const char *ErrMsg) {137  orc_rt_WrapperFunctionResult 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_WrapperFunctionResult values147 * regardless of their state.148 */149static inline void150orc_rt_DisposeWrapperFunctionResult(orc_rt_WrapperFunctionResult *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 given158 * orc_rt_WrapperFunctionResult.159 */160static inline char *161orc_rt_WrapperFunctionResultData(orc_rt_WrapperFunctionResult *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_WrapperFunctionResult.169 *170 * Asserts that we're not trying to access the size of an error value.171 */172static inline size_t173orc_rt_WrapperFunctionResultSize(const orc_rt_WrapperFunctionResult *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 by181 * orc_rt_WrapperFunctionResultInit, 0 otherwise.182 */183static inline size_t184orc_rt_WrapperFunctionResultEmpty(const orc_rt_WrapperFunctionResult *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 this190 * orc_rt_WrapperFunctionResult, or null if there is no error.191 *192 * The orc_rt_WrapperFunctionResult retains ownership of the error193 * string, so it should be copied if the caller wishes to preserve it.194 */195static inline const char *orc_rt_WrapperFunctionResultGetOutOfBandError(196    const orc_rt_WrapperFunctionResult *R) {197  return R->Size == 0 ? R->Data.ValuePtr : 0;198}199 200ORC_RT_C_EXTERN_C_END201 202#endif /* ORC_RT_C_API_H */203