1 /* 2 ** C type conversions. 3 ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice below. 4 ** 5 ** This header contains derived work from LuaJIT's FFI conversion machinery. 6 ** 7 ** Modifications: 8 ** - Adapted for ucode VM integration 9 ** - Removed JIT-specific dependencies 10 ** 11 ** See NOTICE and ATTRIBUTION.md for complete attribution details. 12 */ 13 14 #ifndef _UC_CCONV_H 15 #define _UC_CCONV_H 16 17 #include "uc_ctype.h" 18 19 /* Compressed C type index. ORDER CCX. */ 20 enum { 21 CCX_B, /* Bool. */ 22 CCX_I, /* Integer. */ 23 CCX_F, /* Floating-point number. */ 24 CCX_C, /* Complex. */ 25 CCX_V, /* Vector. */ 26 CCX_P, /* Pointer. */ 27 CCX_A, /* Refarray. */ 28 CCX_S /* Struct/union. */ 29 }; 30 31 /* Convert C type info to compressed C type index. ORDER CT. ORDER CCX. */ 32 static UC_AINLINE uint32_t cconv_idx(CTInfo info) 33 { 34 uint32_t idx = ((info >> 26) & 15u); /* Dispatch bits. */ 35 uc_assertX(ctype_type(info) <= CT_MAYCONVERT, 36 "cannot convert ctype %08x", info); 37 #if UC_64 38 idx = ((uint32_t)(0xf436fff5fff7f021ULL >> 4*idx) & 15u); 39 #else 40 idx = (((idx < 8 ? 0xfff7f021u : 0xf436fff5) >> 4*(idx & 7u)) & 15u); 41 #endif 42 uc_assertX(idx < 8, "cannot convert ctype %08x", info); 43 return idx; 44 } 45 46 #define cconv_idx2(dinfo, sinfo) \ 47 ((cconv_idx((dinfo)) << 3) + cconv_idx((sinfo))) 48 49 #define CCX(dst, src) ((CCX_##dst << 3) + CCX_##src) 50 51 /* Conversion flags. */ 52 #define CCF_CAST 0x00000001u 53 #define CCF_FROMTV 0x00000002u 54 #define CCF_SAME 0x00000004u 55 #define CCF_IGNQUAL 0x00000008u 56 57 #define CCF_ARG_SHIFT 8 58 #define CCF_ARG(n) ((n) << CCF_ARG_SHIFT) 59 #define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT) 60 61 static inline bool 62 uc_cconv_needref(uc_value_t *arg) 63 { 64 switch (ucv_type(arg)) { 65 case UC_STRING: 66 case UC_ARRAY: 67 case UC_OBJECT: 68 case UC_CLOSURE: 69 case UC_CFUNCTION: 70 return true; 71 72 default: 73 return false; 74 } 75 } 76 77 static inline uc_value_t ** 78 uc_cconv_uvref(uc_value_t ***args, uc_value_t ***refs) 79 { 80 uc_value_t **arg = (*args)++; 81 82 return uc_cconv_needref(*arg) ? (*refs)++ : arg; 83 } 84 85 static inline uc_value_t * 86 uc_cconv_addref(uc_value_t **refs, uc_value_t *uv) 87 { 88 if (!refs || ucv_type(uv) != UC_STRING) 89 return uv; 90 91 /* turn tagged pointer short string into heap string */ 92 if ((uintptr_t)uv & 3) { 93 uc_string_t *ustr = xalloc(sizeof(uc_string_t) + ucv_string_length(uv) + 1); 94 95 ustr->length = ucv_string_length(uv); 96 ustr->header.type = UC_STRING; 97 98 memcpy(ustr->str, ucv_string_get(uv), ustr->length); 99 100 uv = &ustr->header; 101 } 102 103 if (!*refs) 104 *refs = ucv_array_new(NULL); 105 106 return ucv_array_push(*refs, ucv_get(uv)); 107 } 108 109 UC_NOAPI int uc_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); 110 UC_NOAPI bool uc_cconv_ct_ct(CTState *cts, CType *d, CType *s, 111 uint8_t *dp, uint8_t *sp, CTInfo flags); 112 UC_NOAPI int uc_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, 113 uc_value_t **uv, uint8_t *sp); 114 UC_NOAPI int uc_cconv_tv_bf(CTState *cts, CType *s, 115 uc_value_t **uv, uint8_t *sp); 116 UC_NOAPI bool uc_cconv_ct_tv(CTState *cts, CType *d, 117 uint8_t *dp, uc_value_t *uv, CTInfo flags, uc_value_t **refs); 118 UC_NOAPI bool uc_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, 119 uc_value_t *uv, uc_value_t **refs); 120 UC_NOAPI int uc_cconv_multi_init(CTState *cts, CType *d, uc_value_t *uv); 121 UC_NOAPI bool uc_cconv_ct_init(CTState *cts, CType *d, CTSize sz, 122 uint8_t *dp, uc_value_t **uv, size_t len, uc_value_t **refs); 123 124 #endif 125
This page was automatically generated by LXR 0.3.1. • OpenWrt