1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
|
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef PHP_FFI_H
#define PHP_FFI_H
extern zend_module_entry ffi_module_entry;
#define phpext_ffi_ptr &ffi_module_entry
typedef enum _zend_ffi_api_restriction {
ZEND_FFI_DISABLED = 0, /* completely disabled */
ZEND_FFI_ENABLED = 1, /* enabled everywhere */
ZEND_FFI_PRELOAD = 2, /* enabled only in preloaded scripts and CLI */
} zend_ffi_api_restriction;
typedef struct _zend_ffi_type zend_ffi_type;
ZEND_BEGIN_MODULE_GLOBALS(ffi)
zend_ffi_api_restriction restriction;
bool is_cli;
/* predefined ffi_types */
HashTable types;
/* preloading */
char *preload;
HashTable *scopes; /* list of preloaded scopes */
/* callbacks */
HashTable *callbacks;
/* weak type references */
HashTable *weak_types;
/* ffi_parser */
JMP_BUF bailout;
unsigned const char *buf;
unsigned const char *end;
unsigned const char *pos;
unsigned const char *text;
int line;
HashTable *symbols;
HashTable *tags;
bool allow_vla;
bool attribute_parsing;
bool persistent;
uint32_t default_type_attr;
ZEND_END_MODULE_GLOBALS(ffi)
ZEND_EXTERN_MODULE_GLOBALS(ffi)
#ifdef PHP_WIN32
# define PHP_FFI_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_FFI_API __attribute__ ((visibility("default")))
#else
# define PHP_FFI_API
#endif
#define FFI_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(ffi, v)
#define ZEND_FFI_DCL_VOID (1<<0)
#define ZEND_FFI_DCL_CHAR (1<<1)
#define ZEND_FFI_DCL_SHORT (1<<2)
#define ZEND_FFI_DCL_INT (1<<3)
#define ZEND_FFI_DCL_LONG (1<<4)
#define ZEND_FFI_DCL_LONG_LONG (1<<5)
#define ZEND_FFI_DCL_FLOAT (1<<6)
#define ZEND_FFI_DCL_DOUBLE (1<<7)
#define ZEND_FFI_DCL_SIGNED (1<<8)
#define ZEND_FFI_DCL_UNSIGNED (1<<9)
#define ZEND_FFI_DCL_BOOL (1<<10)
#define ZEND_FFI_DCL_COMPLEX (1<<11)
#define ZEND_FFI_DCL_STRUCT (1<<12)
#define ZEND_FFI_DCL_UNION (1<<13)
#define ZEND_FFI_DCL_ENUM (1<<14)
#define ZEND_FFI_DCL_TYPEDEF_NAME (1<<15)
#define ZEND_FFI_DCL_TYPE_SPECIFIERS \
(ZEND_FFI_DCL_VOID|ZEND_FFI_DCL_CHAR|ZEND_FFI_DCL_SHORT \
|ZEND_FFI_DCL_INT|ZEND_FFI_DCL_LONG|ZEND_FFI_DCL_LONG_LONG \
|ZEND_FFI_DCL_FLOAT|ZEND_FFI_DCL_DOUBLE|ZEND_FFI_DCL_SIGNED \
|ZEND_FFI_DCL_UNSIGNED|ZEND_FFI_DCL_BOOL|ZEND_FFI_DCL_COMPLEX \
|ZEND_FFI_DCL_STRUCT|ZEND_FFI_DCL_UNION|ZEND_FFI_DCL_ENUM \
|ZEND_FFI_DCL_TYPEDEF_NAME)
#define ZEND_FFI_DCL_TYPEDEF (1<<16)
#define ZEND_FFI_DCL_EXTERN (1<<17)
#define ZEND_FFI_DCL_STATIC (1<<18)
#define ZEND_FFI_DCL_AUTO (1<<19)
#define ZEND_FFI_DCL_REGISTER (1<<20)
#define ZEND_FFI_DCL_STORAGE_CLASS \
(ZEND_FFI_DCL_TYPEDEF|ZEND_FFI_DCL_EXTERN|ZEND_FFI_DCL_STATIC \
|ZEND_FFI_DCL_AUTO|ZEND_FFI_DCL_REGISTER)
#define ZEND_FFI_DCL_CONST (1<<21)
#define ZEND_FFI_DCL_RESTRICT (1<<22)
#define ZEND_FFI_DCL_VOLATILE (1<<23)
#define ZEND_FFI_DCL_ATOMIC (1<<24)
#define ZEND_FFI_DCL_TYPE_QUALIFIERS \
(ZEND_FFI_DCL_CONST|ZEND_FFI_DCL_RESTRICT|ZEND_FFI_DCL_VOLATILE \
|ZEND_FFI_DCL_ATOMIC)
#define ZEND_FFI_DCL_INLINE (1<<25)
#define ZEND_FFI_DCL_NO_RETURN (1<<26)
#define ZEND_FFI_ABI_DEFAULT 0
#define ZEND_FFI_ABI_CDECL 1 // FFI_DEFAULT_ABI
#define ZEND_FFI_ABI_FASTCALL 2 // FFI_FASTCALL
#define ZEND_FFI_ABI_THISCALL 3 // FFI_THISCALL
#define ZEND_FFI_ABI_STDCALL 4 // FFI_STDCALL
#define ZEND_FFI_ABI_PASCAL 5 // FFI_PASCAL
#define ZEND_FFI_ABI_REGISTER 6 // FFI_REGISTER
#define ZEND_FFI_ABI_MS 7 // FFI_MS_CDECL
#define ZEND_FFI_ABI_SYSV 8 // FFI_SYSV
#define ZEND_FFI_ABI_VECTORCALL 9 // FFI_VECTORCALL
#define ZEND_FFI_ATTR_CONST (1<<0)
#define ZEND_FFI_ATTR_INCOMPLETE_TAG (1<<1)
#define ZEND_FFI_ATTR_VARIADIC (1<<2)
#define ZEND_FFI_ATTR_INCOMPLETE_ARRAY (1<<3)
#define ZEND_FFI_ATTR_VLA (1<<4)
#define ZEND_FFI_ATTR_UNION (1<<5)
#define ZEND_FFI_ATTR_PACKED (1<<6)
#define ZEND_FFI_ATTR_MS_STRUCT (1<<7)
#define ZEND_FFI_ATTR_GCC_STRUCT (1<<8)
#define ZEND_FFI_ATTR_PERSISTENT (1<<9)
#define ZEND_FFI_ATTR_STORED (1<<10)
#define ZEND_FFI_STRUCT_ATTRS \
(ZEND_FFI_ATTR_UNION|ZEND_FFI_ATTR_PACKED|ZEND_FFI_ATTR_MS_STRUCT \
|ZEND_FFI_ATTR_GCC_STRUCT)
#define ZEND_FFI_ENUM_ATTRS \
(ZEND_FFI_ATTR_PACKED)
#define ZEND_FFI_ARRAY_ATTRS \
(ZEND_FFI_ATTR_CONST|ZEND_FFI_ATTR_VLA|ZEND_FFI_ATTR_INCOMPLETE_ARRAY)
#define ZEND_FFI_FUNC_ATTRS \
(ZEND_FFI_ATTR_VARIADIC)
#define ZEND_FFI_POINTER_ATTRS \
(ZEND_FFI_ATTR_CONST)
typedef struct _zend_ffi_dcl {
uint32_t flags;
uint32_t align;
uint16_t attr;
uint16_t abi;
zend_ffi_type *type;
} zend_ffi_dcl;
#define ZEND_FFI_ATTR_INIT {0, 0, 0, 0, NULL}
typedef enum _zend_ffi_val_kind {
ZEND_FFI_VAL_EMPTY,
ZEND_FFI_VAL_ERROR,
ZEND_FFI_VAL_INT32,
ZEND_FFI_VAL_INT64,
ZEND_FFI_VAL_UINT32,
ZEND_FFI_VAL_UINT64,
ZEND_FFI_VAL_FLOAT,
ZEND_FFI_VAL_DOUBLE,
ZEND_FFI_VAL_LONG_DOUBLE,
ZEND_FFI_VAL_CHAR,
ZEND_FFI_VAL_STRING,
ZEND_FFI_VAL_NAME, /* attribute value */
} zend_ffi_val_kind;
#ifdef HAVE_LONG_DOUBLE
typedef long double zend_ffi_double;
#else
typedef double zend_ffi_double;
#endif
typedef struct _zend_ffi_val {
zend_ffi_val_kind kind;
union {
uint64_t u64;
int64_t i64;
zend_ffi_double d;
signed char ch;
struct {
const char *str;
size_t len;
};
};
} zend_ffi_val;
zend_result zend_ffi_parse_decl(const char *str, size_t len);
zend_result zend_ffi_parse_type(const char *str, size_t len, zend_ffi_dcl *dcl);
void zend_ffi_cleanup_dcl(zend_ffi_dcl *dcl);
/* parser callbacks */
void ZEND_NORETURN zend_ffi_parser_error(const char *msg, ...);
bool zend_ffi_is_typedef_name(const char *name, size_t name_len);
void zend_ffi_resolve_typedef(const char *name, size_t name_len, zend_ffi_dcl *dcl);
void zend_ffi_resolve_const(const char *name, size_t name_len, zend_ffi_val *val);
void zend_ffi_declare_tag(const char *name, size_t name_len, zend_ffi_dcl *dcl, bool incomplete);
void zend_ffi_make_enum_type(zend_ffi_dcl *dcl);
void zend_ffi_add_enum_val(zend_ffi_dcl *enum_dcl, const char *name, size_t name_len, zend_ffi_val *val, int64_t *min, int64_t *max, int64_t *last);
void zend_ffi_make_struct_type(zend_ffi_dcl *dcl);
void zend_ffi_add_field(zend_ffi_dcl *struct_dcl, const char *name, size_t name_len, zend_ffi_dcl *field_dcl);
void zend_ffi_add_anonymous_field(zend_ffi_dcl *struct_dcl, zend_ffi_dcl *field_dcl);
void zend_ffi_add_bit_field(zend_ffi_dcl *struct_dcl, const char *name, size_t name_len, zend_ffi_dcl *field_dcl, zend_ffi_val *bits);
void zend_ffi_adjust_struct_size(zend_ffi_dcl *dcl);
void zend_ffi_make_pointer_type(zend_ffi_dcl *dcl);
void zend_ffi_make_array_type(zend_ffi_dcl *dcl, zend_ffi_val *len);
void zend_ffi_make_func_type(zend_ffi_dcl *dcl, HashTable *args, zend_ffi_dcl *nested_dcl);
void zend_ffi_add_arg(HashTable **args, const char *name, size_t name_len, zend_ffi_dcl *arg_dcl);
void zend_ffi_declare(const char *name, size_t name_len, zend_ffi_dcl *dcl);
void zend_ffi_add_attribute(zend_ffi_dcl *dcl, const char *name, size_t name_len);
void zend_ffi_add_attribute_value(zend_ffi_dcl *dcl, const char *name, size_t name_len, int n, zend_ffi_val *val);
void zend_ffi_add_msvc_attribute_value(zend_ffi_dcl *dcl, const char *name, size_t name_len, zend_ffi_val *val);
void zend_ffi_set_abi(zend_ffi_dcl *dcl, uint16_t abi);
void zend_ffi_nested_declaration(zend_ffi_dcl *dcl, zend_ffi_dcl *nested_dcl);
void zend_ffi_align_as_type(zend_ffi_dcl *dcl, zend_ffi_dcl *align_dcl);
void zend_ffi_align_as_val(zend_ffi_dcl *dcl, zend_ffi_val *align_val);
void zend_ffi_validate_type_name(zend_ffi_dcl *dcl);
void zend_ffi_expr_conditional(zend_ffi_val *val, zend_ffi_val *op2, zend_ffi_val *op3);
void zend_ffi_expr_bool_or(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_bool_and(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_bw_or(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_bw_xor(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_bw_and(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_is_equal(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_is_not_equal(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_is_less(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_is_greater(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_is_less_or_equal(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_is_greater_or_equal(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_shift_left(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_shift_right(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_add(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_sub(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_mul(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_div(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_mod(zend_ffi_val *val, zend_ffi_val *op2);
void zend_ffi_expr_cast(zend_ffi_val *val, zend_ffi_dcl *dcl);
void zend_ffi_expr_plus(zend_ffi_val *val);
void zend_ffi_expr_neg(zend_ffi_val *val);
void zend_ffi_expr_bw_not(zend_ffi_val *val);
void zend_ffi_expr_bool_not(zend_ffi_val *val);
void zend_ffi_expr_sizeof_val(zend_ffi_val *val);
void zend_ffi_expr_sizeof_type(zend_ffi_val *val, zend_ffi_dcl *dcl);
void zend_ffi_expr_alignof_val(zend_ffi_val *val);
void zend_ffi_expr_alignof_type(zend_ffi_val *val, zend_ffi_dcl *dcl);
static zend_always_inline void zend_ffi_val_error(zend_ffi_val *val) /* {{{ */
{
val->kind = ZEND_FFI_VAL_ERROR;
}
/* }}} */
void zend_ffi_val_number(zend_ffi_val *val, int base, const char *str, size_t str_len);
void zend_ffi_val_float_number(zend_ffi_val *val, const char *str, size_t str_len);
void zend_ffi_val_string(zend_ffi_val *val, const char *str, size_t str_len);
void zend_ffi_val_character(zend_ffi_val *val, const char *str, size_t str_len);
#endif /* PHP_FFI_H */
|