brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 43867e9 Raw
206 lines · c
1/*===--------- WrapperFunction.h - Wrapper function utils ---------*- 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|* Defines orc_rt_WrapperFunctionBuffer and related APIs.                     *|11|*                                                                            *|12\*===----------------------------------------------------------------------===*/13 14#ifndef ORC_RT_C_WRAPPERFUNCTION_H15#define ORC_RT_C_WRAPPERFUNCTION_H16 17#include "orc-rt-c/CoreTypes.h"18#include "orc-rt-c/ExternC.h"19 20#include <assert.h>21#include <stdlib.h>22#include <string.h>23 24ORC_RT_C_EXTERN_C_BEGIN25 26typedef union {27  char *ValuePtr;28  char Value[sizeof(char *)];29} orc_rt_WrapperFunctionBufferDataUnion;30 31/**32 * orc_rt_WrapperFunctionBuffer is a kind of C-SmallVector with an33 * out-of-band error state.34 *35 * If Size == 0 and Data.ValuePtr is non-zero then the value is in the36 * 'out-of-band error' state, and Data.ValuePtr points at a malloc-allocated,37 * null-terminated string error message.38 *39 * If Size <= sizeof(orc_rt_WrapperFunctionBufferData) then the value is in40 * the 'small' state and the content is held in the first Size bytes of41 * Data.Value.42 *43 * If Size > sizeof(orc_rt_WrapperFunctionBufferData) then the value is in the44 * 'large' state and the content is held in the first Size bytes of the45 * memory pointed to by Data.ValuePtr. This memory must have been allocated by46 * malloc, and will be freed with free when this value is destroyed.47 */48typedef struct {49  orc_rt_WrapperFunctionBufferDataUnion Data;50  size_t Size;51} orc_rt_WrapperFunctionBuffer;52 53/**54 * Asynchronous return function for an orc-rt wrapper function.55 */56typedef void (*orc_rt_WrapperFunctionReturn)(57    orc_rt_SessionRef S, uint64_t CallId,58    orc_rt_WrapperFunctionBuffer ResultBytes);59 60/**61 * orc-rt wrapper function prototype.62 *63 * ArgBytes contains the serialized arguments for the wrapper function.64 * Session holds a reference to the session object.65 * CallId holds a pointer to the context object for this particular call.66 * Return holds a pointer to the return function.67 */68typedef void (*orc_rt_WrapperFunction)(orc_rt_SessionRef S, uint64_t CallId,69                                       orc_rt_WrapperFunctionReturn Return,70                                       orc_rt_WrapperFunctionBuffer ArgBytes);71 72/**73 * Zero-initialize an orc_rt_WrapperFunctionBuffer.74 */75static inline void76orc_rt_WrapperFunctionBufferInit(orc_rt_WrapperFunctionBuffer *B) {77  B->Size = 0;78  B->Data.ValuePtr = 0;79}80 81/**82 * Create an orc_rt_WrapperFunctionBuffer with an uninitialized buffer of83 * size Size. The buffer is returned via the DataPtr argument.84 */85static inline orc_rt_WrapperFunctionBuffer86orc_rt_WrapperFunctionBufferAllocate(size_t Size) {87  orc_rt_WrapperFunctionBuffer B;88  B.Size = Size;89  // If Size is 0 ValuePtr must be 0 or it is considered an out-of-band error.90  B.Data.ValuePtr = 0;91  if (Size > sizeof(B.Data.Value))92    B.Data.ValuePtr = (char *)malloc(Size);93  return B;94}95 96/**97 * Create an orc_rt_WrapperFunctionBuffer from the given data range.98 */99static inline orc_rt_WrapperFunctionBuffer100orc_rt_CreateWrapperFunctionBufferFromRange(const char *Data, size_t Size) {101  orc_rt_WrapperFunctionBuffer B;102  B.Size = Size;103  if (B.Size > sizeof(B.Data.Value)) {104    char *Tmp = (char *)malloc(Size);105    memcpy(Tmp, Data, Size);106    B.Data.ValuePtr = Tmp;107  } else108    memcpy(B.Data.Value, Data, Size);109  return B;110}111 112/**113 * Create an orc_rt_WrapperFunctionBuffer by copying the given string,114 * including the null-terminator.115 *116 * This function copies the input string. The client is responsible for freeing117 * the ErrMsg arg.118 */119static inline orc_rt_WrapperFunctionBuffer120orc_rt_CreateWrapperFunctionBufferFromString(const char *Source) {121  return orc_rt_CreateWrapperFunctionBufferFromRange(Source,122                                                     strlen(Source) + 1);123}124 125/**126 * Create an orc_rt_WrapperFunctionBuffer representing an out-of-band127 * error.128 *129 * This function copies the input string. The client is responsible for freeing130 * the ErrMsg arg.131 */132static inline orc_rt_WrapperFunctionBuffer133orc_rt_CreateWrapperFunctionBufferFromOutOfBandError(const char *ErrMsg) {134  orc_rt_WrapperFunctionBuffer B;135  B.Size = 0;136  char *Tmp = (char *)malloc(strlen(ErrMsg) + 1);137  strcpy(Tmp, ErrMsg);138  B.Data.ValuePtr = Tmp;139  return B;140}141 142/**143 * This should be called to destroy orc_rt_WrapperFunctionBuffer values144 * regardless of their state.145 */146static inline void147orc_rt_WrapperFunctionBufferDispose(orc_rt_WrapperFunctionBuffer *B) {148  if (B->Size > sizeof(B->Data.Value) || (B->Size == 0 && B->Data.ValuePtr))149    free(B->Data.ValuePtr);150}151 152/**153 * Get a pointer to the data contained in the given154 * orc_rt_WrapperFunctionBuffer.155 */156static inline char *157orc_rt_WrapperFunctionBufferData(orc_rt_WrapperFunctionBuffer *B) {158  assert((B->Size != 0 || B->Data.ValuePtr == NULL) &&159         "Cannot get data for out-of-band error value");160  return B->Size > sizeof(B->Data.Value) ? B->Data.ValuePtr : B->Data.Value;161}162 163static inline const char *164orc_rt_WrapperFunctionBufferConstData(const orc_rt_WrapperFunctionBuffer *B) {165  assert((B->Size != 0 || B->Data.ValuePtr == NULL) &&166         "Cannot get data for out-of-band error value");167  return B->Size > sizeof(B->Data.Value) ? B->Data.ValuePtr : B->Data.Value;168}169 170/**171 * Safely get the size of the given orc_rt_WrapperFunctionBuffer.172 *173 * Asserts that we're not trying to access the size of an error value.174 */175static inline size_t176orc_rt_WrapperFunctionBufferSize(const orc_rt_WrapperFunctionBuffer *B) {177  assert((B->Size != 0 || B->Data.ValuePtr == NULL) &&178         "Cannot get size for out-of-band error value");179  return B->Size;180}181 182/**183 * Returns 1 if this value is equivalent to a value just initialized by184 * orc_rt_WrapperFunctionBufferInit, 0 otherwise.185 */186static inline size_t187orc_rt_WrapperFunctionBufferEmpty(const orc_rt_WrapperFunctionBuffer *B) {188  return B->Size == 0 && B->Data.ValuePtr == 0;189}190 191/**192 * Returns a pointer to the out-of-band error string for this193 * orc_rt_WrapperFunctionBuffer, or null if there is no error.194 *195 * The orc_rt_WrapperFunctionBuffer retains ownership of the error196 * string, so it should be copied if the caller wishes to preserve it.197 */198static inline const char *orc_rt_WrapperFunctionBufferGetOutOfBandError(199    const orc_rt_WrapperFunctionBuffer *B) {200  return B->Size == 0 ? B->Data.ValuePtr : 0;201}202 203ORC_RT_C_EXTERN_C_END204 205#endif /* ORC_RT_C_WRAPPERFUNCTION_H */206