• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/lib/ffi/uc_cconv.h

  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