41#define GET_DL_ERROR() php_win_err()
44#define GET_DL_ERROR() DL_ERROR()
56#ifndef __BIGGEST_ALIGNMENT__
58# define __BIGGEST_ALIGNMENT__ sizeof(size_t)
69static const char *zend_ffi_tag_kind_name[3] = {
"enum",
"struct",
"union"};
81#ifdef HAVE_LONG_DOUBLE
82 ZEND_FFI_TYPE_LONGDOUBLE,
177#define ZEND_FFI_TYPE_OWNED (1<<0)
179#define ZEND_FFI_TYPE(t) \
180 ((zend_ffi_type*)(((uintptr_t)(t)) & ~ZEND_FFI_TYPE_OWNED))
182#define ZEND_FFI_TYPE_IS_OWNED(t) \
183 (((uintptr_t)(t)) & ZEND_FFI_TYPE_OWNED)
185#define ZEND_FFI_TYPE_MAKE_OWNED(t) \
186 ((zend_ffi_type*)(((uintptr_t)(t)) | ZEND_FFI_TYPE_OWNED))
188#define ZEND_FFI_SIZEOF_ARG \
189 MAX(FFI_SIZEOF_ARG, sizeof(double))
225static char *zend_ffi_parse_directives(
const char *filename,
char *code_pos,
char **scope_name,
char **
lib,
bool preload);
239 _zend_ffi_type_dtor(
type);
249 object->extra_flags = 0;
252 object->properties =
NULL;
263 zend_ffi_object_init(&
cdata->std, class_type);
275 uint32_t dst_argc, src_argc, i;
292 dst_argc = dst_type->
func.
args ? zend_hash_num_elements(dst_type->
func.
args) : 0;
293 src_argc = src_type->
func.
args ? zend_hash_num_elements(src_type->
func.
args) : 0;
294 if (dst_argc != src_argc) {
304 for (i = 0; i < dst_argc; i++) {
305 dst_arg = zend_hash_index_find_ptr(dst_type->
func.
args, i);
306 src_arg = zend_hash_index_find_ptr(src_type->
func.
args, i);
319 if (dst_type == src_type) {
321 }
else if (dst_type->
kind == src_type->
kind) {
332 return zend_ffi_func_ptr_are_compatible(dst_type, src_type);
357static ffi_type* zend_ffi_face_struct_add_fields(ffi_type* t,
zend_ffi_type *
type,
int *i,
size_t size)
364 t->elements[(*i)++] = &ffi_type_float;
367 t->elements[(*i)++] = &ffi_type_double;
369#ifdef HAVE_LONG_DOUBLE
370 case ZEND_FFI_TYPE_LONGDOUBLE:
371 t->elements[(*i)++] = &ffi_type_longdouble;
378 t->elements[(*i)++] = &ffi_type_uint8;
382 t->elements[(*i)++] = &ffi_type_uint16;
386 t->elements[(*i)++] = &ffi_type_uint32;
390 t->elements[(*i)++] = &ffi_type_uint64;
393 t->elements[(*i)++] = &ffi_type_pointer;
401 if (num_fields > 1) {
402 size +=
sizeof(ffi_type*) * (num_fields - 1);
404 t->elements = (ffi_type**)(t + 1);
406 t = zend_ffi_face_struct_add_fields(t, field_type, i,
size);
410 t->elements[(*i)++] = &ffi_type_void;
425 zend_hash_num_elements(&
type->record.fields) : 1;
426 size_t size =
sizeof(ffi_type) +
sizeof(ffi_type*) * (num_fields + 1);
430 t->size =
type->size;
431 t->alignment =
type->align;
432 t->type = FFI_TYPE_STRUCT;
433 t->elements = (ffi_type**)(t + 1);
435 t = zend_ffi_face_struct_add_fields(t,
type, &i,
size);
436 t->elements[i] =
NULL;
448 return &ffi_type_float;
450 return &ffi_type_double;
451#ifdef HAVE_LONG_DOUBLE
452 case ZEND_FFI_TYPE_LONGDOUBLE:
453 return &ffi_type_longdouble;
456 return &ffi_type_uint8;
458 return &ffi_type_sint8;
460 return &ffi_type_uint16;
462 return &ffi_type_sint16;
464 return &ffi_type_uint32;
466 return &ffi_type_sint32;
468 return &ffi_type_uint64;
470 return &ffi_type_sint64;
472 return &ffi_type_pointer;
474 return &ffi_type_void;
476 return &ffi_type_uint8;
478 return &ffi_type_sint8;
483 return zend_ffi_make_fake_struct_type(
type);
495 zend_ffi_object_init(&
cdata->std, zend_ffi_cdata_ce);
496 cdata->std.handlers =
498 &zend_ffi_cdata_value_handlers :
499 &zend_ffi_cdata_handlers;
511 zend_ffi_object_init(&
cdata->std, zend_ffi_cdata_ce);
524 zend_ffi_object_init(&
cdata->std, zend_ffi_cdata_ce);
525 cdata->std.handlers =
527 &zend_ffi_cdata_value_handlers :
528 &zend_ffi_cdata_handlers;
558#ifdef HAVE_LONG_DOUBLE
559 case ZEND_FFI_TYPE_LONGDOUBLE:
600 }
else if (debug_union) {
638 size_t bit = field->first_bit;
639 size_t last_bit = bit + field->bits - 1;
640 uint8_t *
p = (uint8_t *)
ptr + bit / 8;
641 uint8_t *last_p = (uint8_t *)
ptr + last_bit / 8;
642 size_t pos = bit % 8;
643 size_t insert_pos = 0;
649 mask = (1U << field->bits) - 1U;
650 return (*
p >>
pos) & mask;
655 size_t num_bits = 8 -
pos;
656 mask = (1U << num_bits) - 1U;
658 insert_pos += num_bits;
663 val |= (uint64_t) *
p++ << insert_pos;
669 size_t num_bits = last_bit % 8 + 1;
670 mask = (1U << num_bits) - 1U;
671 val |= (uint64_t) (*
p & mask) << insert_pos;
680 uint64_t
val = zend_ffi_bit_field_read(
ptr, field);
687 uint64_t shift = 64 - (field->bits % 64);
689 val = (int64_t)(
val << shift) >> shift;
698 uint64_t
val = zval_get_long(
value);
699 size_t bit = field->first_bit;
700 size_t last_bit = bit + field->bits - 1;
701 uint8_t *
p = (uint8_t *)
ptr + bit / 8;
702 uint8_t *last_p = (uint8_t *)
ptr + last_bit / 8;
703 size_t pos = bit % 8;
708 mask = ((1U << field->bits) - 1U) <<
pos;
709 *
p = (*
p & ~mask) | ((
val <<
pos) & mask);
715 size_t num_bits = 8 -
pos;
716 mask = ((1U << num_bits) - 1U) <<
pos;
717 *
p = (*
p & ~mask) | ((
val <<
pos) & mask);
730 size_t num_bits = last_bit % 8 + 1;
731 mask = (1U << num_bits) - 1U;
732 *
p = (*
p & ~mask) | (
val & mask);
765#ifdef HAVE_LONG_DOUBLE
766 case ZEND_FFI_TYPE_LONGDOUBLE:
772 lval = zval_get_long(
value);
773 *(uint8_t*)
ptr = lval;
776 lval = zval_get_long(
value);
777 *(int8_t*)
ptr = lval;
780 lval = zval_get_long(
value);
781 *(uint16_t*)
ptr = lval;
784 lval = zval_get_long(
value);
785 *(int16_t*)
ptr = lval;
788 lval = zval_get_long(
value);
789 *(uint32_t*)
ptr = lval;
792 lval = zval_get_long(
value);
793 *(int32_t*)
ptr = lval;
796 lval = zval_get_long(
value);
797 *(uint64_t*)
ptr = lval;
800 lval = zval_get_long(
value);
801 *(int64_t*)
ptr = lval;
807 str = zval_get_tmp_string(
value, &tmp_str);
811 zend_tmp_string_release(tmp_str);
812 zend_ffi_assign_incompatible(
value,
type);
815 zend_tmp_string_release(tmp_str);
832 zend_throw_error(zend_ffi_exception_ce,
"Attempt to perform assign of owned C pointer");
842 zend_throw_error(zend_ffi_exception_ce,
"Attempt to perform assign pointer to owned C data");
860 zend_ffi_assign_incompatible(
value,
type);
866 zend_ffi_assign_incompatible(
value,
type);
873#if defined(ZEND_WIN32) && (defined(HAVE_FFI_FASTCALL) || defined(HAVE_FFI_STDCALL) || defined(HAVE_FFI_VECTORCALL_PARTIAL))
890 switch (
type->func.abi) {
891# ifdef HAVE_FFI_FASTCALL
895# ifdef HAVE_FFI_STDCALL
899# ifdef HAVE_FFI_VECTORCALL_PARTIAL
900 case FFI_VECTORCALL_PARTIAL:
905 return zend_string_copy(
name);
910typedef struct _zend_ffi_callback_data {
919} zend_ffi_callback_data;
921static void zend_ffi_callback_hash_dtor(
zval *
zv)
923 zend_ffi_callback_data *callback_data =
Z_PTR_P(
zv);
925 ffi_closure_free(callback_data->callback);
926 if (callback_data->fcc.function_handler->common.fn_flags &
ZEND_ACC_CLOSURE) {
929 for (
int i = 0; i < callback_data->arg_count; ++i) {
930 if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
931 efree(callback_data->arg_types[i]);
934 if (callback_data->ret_type->type == FFI_TYPE_STRUCT) {
935 efree(callback_data->ret_type);
937 efree(callback_data);
941static void zend_ffi_callback_trampoline(ffi_cif* cif,
void*
ret,
void**
args,
void*
data)
943 zend_ffi_callback_data *callback_data = (zend_ffi_callback_data*)
data;
957 if (callback_data->type->func.args) {
973 if (callback_data->arg_count) {
976 for (
n = 0;
n < callback_data->arg_count;
n++) {
986 ret_type =
ZEND_FFI_TYPE(callback_data->type->func.ret_type);
988 zend_ffi_zval_to_cdata(
ret, ret_type, &
retval);
990#ifdef WORDS_BIGENDIAN
991 if (ret_type->
size <
sizeof(ffi_arg)
995 switch (ret_type->
size) {
997 *(ffi_arg*)
ret = *(uint8_t*)
ret;
1000 *(ffi_arg*)
ret = *(uint16_t*)
ret;
1003 *(ffi_arg*)
ret = *(uint32_t*)
ret;
1023 zend_ffi_callback_data *callback_data;
1026 zend_throw_error(zend_ffi_exception_ce,
"Variadic function closures are not supported");
1035 arg_count =
type->func.args ? zend_hash_num_elements(
type->func.args) : 0;
1036 if (arg_count < fcc.function_handler->common.required_num_args) {
1037 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign an invalid callback, insufficient number of arguments");
1041 callback = ffi_closure_alloc(
sizeof(ffi_closure), &code);
1047 callback_data =
emalloc(
sizeof(zend_ffi_callback_data) +
sizeof(ffi_type*) * arg_count);
1049 callback_data->type =
type;
1050 callback_data->callback =
callback;
1051 callback_data->code = code;
1052 callback_data->arg_count = arg_count;
1054 if (
type->func.args) {
1060 callback_data->arg_types[
n] = zend_ffi_get_type(arg_type);
1061 if (!callback_data->arg_types[
n]) {
1062 zend_ffi_pass_unsupported(arg_type);
1063 for (
int i = 0; i <
n; ++i) {
1064 if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
1065 efree(callback_data->arg_types[i]);
1068 efree(callback_data);
1075 callback_data->ret_type = zend_ffi_get_type(
ZEND_FFI_TYPE(
type->func.ret_type));
1076 if (!callback_data->ret_type) {
1077 zend_ffi_return_unsupported(
type->func.ret_type);
1078 for (
int i = 0; i < callback_data->arg_count; ++i) {
1079 if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
1080 efree(callback_data->arg_types[i]);
1083 efree(callback_data);
1088 if (ffi_prep_cif(&callback_data->cif,
type->func.abi, callback_data->arg_count, callback_data->ret_type, callback_data->arg_types) != FFI_OK) {
1090 goto free_on_failure;
1093 if (ffi_prep_closure_loc(
callback, &callback_data->cif, zend_ffi_callback_trampoline, callback_data, code) != FFI_OK) {
1096 for (
int i = 0; i < callback_data->arg_count; ++i) {
1097 if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
1098 efree(callback_data->arg_types[i]);
1101 if (callback_data->ret_type->type == FFI_TYPE_STRUCT) {
1102 efree(callback_data->ret_type);
1104 efree(callback_data);
1113 zend_hash_next_index_insert_ptr(
FFI_G(
callbacks), callback_data);
1132 return &
EG(uninitialized_zval);
1137 zend_throw_error(zend_ffi_exception_ce,
"Only 'cdata' property may be read");
1138 return &
EG(uninitialized_zval);
1154 return &
EG(uninitialized_zval);
1159 zend_throw_error(zend_ffi_exception_ce,
"Only 'cdata' property may be set");
1160 return &
EG(uninitialized_zval);
1185#ifdef HAVE_LONG_DOUBLE
1186 case ZEND_FFI_TYPE_LONGDOUBLE:
1253 if (cache_slot && *cache_slot ==
type) {
1254 field = *(cache_slot + 1);
1262 return &
EG(uninitialized_zval);
1266 field = zend_hash_find_ptr(&
type->record.fields, field_name);
1268 zend_throw_error(zend_ffi_exception_ce,
"Attempt to read undefined field '%s' of C struct/union",
ZSTR_VAL(field_name));
1269 return &
EG(uninitialized_zval);
1274 *(cache_slot + 1) = field;
1282 return &
EG(uninitialized_zval);
1284 ptr = (
void*)(*(
char**)
ptr);
1287 return &
EG(uninitialized_zval);
1295 return &
EG(uninitialized_zval);
1306 field->type = field_type = zend_ffi_remember_type(field_type);
1309 ptr = (
void*)(((
char*)
ptr) + field->offset);
1312 zend_ffi_bit_field_to_zval(
ptr, field,
rv);
1326 if (cache_slot && *cache_slot ==
type) {
1327 field = *(cache_slot + 1);
1330 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign field '%s' to uninitialized FFI\\CData object",
ZSTR_VAL(field_name));
1338 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign field '%s' of non C struct/union",
ZSTR_VAL(field_name));
1343 field = zend_hash_find_ptr(&
type->record.fields, field_name);
1345 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign undefined field '%s' of C struct/union",
ZSTR_VAL(field_name));
1351 *(cache_slot + 1) = field;
1361 ptr = (
void*)(*(
char**)
ptr);
1376 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign read-only location");
1384 ptr = (
void*)(((
char*)
ptr) + field->offset);
1387 zend_ffi_zval_to_bit_field(
ptr, field,
value);
1406 return &
EG(uninitialized_zval);
1411 dim_type =
type->array.type;
1416 type->array.type = dim_type = zend_ffi_remember_type(dim_type);
1422 return &
EG(uninitialized_zval);
1428 dim_type =
type->pointer.type;
1433 type->pointer.type = dim_type = zend_ffi_remember_type(dim_type);
1438 return &
EG(uninitialized_zval);
1442 zend_throw_error(zend_ffi_exception_ce,
"Attempt to read element of non C array");
1443 return &
EG(uninitialized_zval);
1460 zend_throw_error(zend_ffi_exception_ce,
"Cannot add next element to object of type FFI\\CData");
1490 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign element of non C array");
1495 zend_throw_error(zend_ffi_exception_ce,
"Attempt to assign read-only location");
1503#define MAX_TYPE_NAME_LEN 256
1514 if (
buf->start <
buf->buf) {
1527 buf->end = zend_mempcpy(
buf->end, str,
len);
1538 switch (
type->kind) {
1548#ifdef HAVE_LONG_DOUBLE
1549 case ZEND_FFI_TYPE_LONGDOUBLE:
1550 name =
"long double";
1578 if (
type->enumeration.tag_name) {
1581 zend_ffi_ctype_name_prepend(
buf,
"<anonymous>",
sizeof(
"<anonymous>")-1);
1592 if (!zend_ffi_ctype_name_prepend(
buf,
"*", 1)) {
1601 if (!zend_ffi_ctype_name_prepend(
buf,
"(", 1)
1602 || !zend_ffi_ctype_name_append(
buf,
")", 1)) {
1606 if (!zend_ffi_ctype_name_append(
buf,
"(", 1)
1607 || !zend_ffi_ctype_name_append(
buf,
")", 1)) {
1615 if (!zend_ffi_ctype_name_prepend(
buf,
"(", 1)
1616 || !zend_ffi_ctype_name_append(
buf,
")", 1)) {
1620 if (!zend_ffi_ctype_name_append(
buf,
"[", 1)) {
1624 if (!zend_ffi_ctype_name_append(
buf,
"*", 1)) {
1629 char *
s = zend_print_long_to_buf(str +
sizeof(str) - 1,
type->array.length);
1631 if (!zend_ffi_ctype_name_append(
buf,
s,
strlen(
s))) {
1635 if (!zend_ffi_ctype_name_append(
buf,
"]", 1)) {
1642 if (
type->record.tag_name) {
1645 zend_ffi_ctype_name_prepend(
buf,
"<anonymous>",
sizeof(
"<anonymous>")-1);
1649 if (
type->record.tag_name) {
1652 zend_ffi_ctype_name_prepend(
buf,
"<anonymous>",
sizeof(
"<anonymous>")-1);
1678 zend_throw_error(zend_ffi_exception_ce,
"FFI return struct/union is not implemented");
1680 zend_throw_error(zend_ffi_exception_ce,
"FFI return array is not implemented");
1682 zend_throw_error(zend_ffi_exception_ce,
"FFI internal error. Unsupported return type");
1691 zend_throw_error(zend_ffi_exception_ce,
"FFI passing struct/union is not implemented");
1693 zend_throw_error(zend_ffi_exception_ce,
"FFI passing array is not implemented");
1695 zend_throw_error(zend_ffi_exception_ce,
"FFI internal error. Unsupported parameter type");
1705 if (!zend_ffi_ctype_name(&buf1,
type)) {
1706 zend_throw_error(zend_ffi_exception_ce,
"Passing incompatible argument %d of C function '%s'",
n + 1,
ZSTR_VAL(
EX(
func)->internal_function.function_name));
1714 if (!zend_ffi_ctype_name(&buf2,
type)) {
1715 zend_throw_error(zend_ffi_exception_ce,
"Passing incompatible argument %d of C function '%s', expecting '%s'",
n + 1,
ZSTR_VAL(
EX(
func)->internal_function.function_name), buf1.
start);
1718 zend_throw_error(zend_ffi_exception_ce,
"Passing incompatible argument %d of C function '%s', expecting '%s', found '%s'",
n + 1,
ZSTR_VAL(
EX(
func)->internal_function.function_name), buf1.
start, buf2.
start);
1732 if (!zend_ffi_ctype_name(&buf1,
type)) {
1733 zend_throw_error(zend_ffi_exception_ce,
"Incompatible types when assigning");
1741 if (!zend_ffi_ctype_name(&buf2,
type)) {
1742 zend_throw_error(zend_ffi_exception_ce,
"Incompatible types when assigning to type '%s'", buf1.
start);
1745 zend_throw_error(zend_ffi_exception_ce,
"Incompatible types when assigning to type '%s' from type '%s'", buf1.
start, buf2.
start);
1759 if (!zend_ffi_ctype_name(&
buf,
type)) {
1760 return zend_string_copy(
prefix);
1776static int zend_ffi_cdata_compare_objects(
zval *o1,
zval *o2)
1796 zend_throw_error(zend_ffi_exception_ce,
"Comparison of incompatible C types");
1807 zend_throw_error(zend_ffi_exception_ce,
"Attempt to count() on non C array");
1828 base_cdata->
type = base_type;
1831 base_cdata->
type = base_type = zend_ffi_remember_type(base_type);
1835 cdata->type = base_type;
1836 ptr = (
char*)(*(
void**)base_cdata->
ptr);
1855 base_type->
array.
type = ptr_type = zend_ffi_remember_type(ptr_type);
1862 ptr = (
char*)base_cdata->
ptr;
1901 p1 = (
char*)(*(
void**)
cdata1->ptr);
1908 p2 = (
char*)(*(
void**)
cdata2->ptr);
1913 if (zend_ffi_is_same_type(
t1,
t2)) {
1979 return &
EG(uninitialized_zval);
1981 dim_type =
type->array.type;
1986 type->array.type = dim_type = zend_ffi_remember_type(dim_type);
1993 return &iter->
value;
2019 zend_ffi_cdata_it_dtor,
2020 zend_ffi_cdata_it_valid,
2021 zend_ffi_cdata_it_get_current_data,
2022 zend_ffi_cdata_it_get_current_key,
2023 zend_ffi_cdata_it_move_forward,
2024 zend_ffi_cdata_it_rewind,
2036 zend_throw_error(zend_ffi_exception_ce,
"Attempt to iterate on non C array");
2046 iter->
it.
funcs = &zend_ffi_cdata_it_funcs;
2071 switch (
type->kind) {
2079#ifdef HAVE_LONG_DOUBLE
2080 case ZEND_FFI_TYPE_LONGDOUBLE:
2122 void *f_ptr = (
void*)(((
char*)
ptr) + f->
offset);
2126 zend_ffi_bit_field_to_zval(
ptr, f, &tmp);
2135 for (
n = 0;
n <
type->array.length;
n++) {
2164 zend_throw_error(zend_ffi_exception_ce,
"Attempt to call non C function pointer");
2171 zend_throw_error(zend_ffi_exception_ce,
"Attempt to call non C function pointer");
2188 func->common.arg_flags[0] = 0;
2189 func->common.arg_flags[1] = 0;
2190 func->common.arg_flags[2] = 0;
2194 func->common.num_args = 0;
2195 func->common.required_num_args =
type->func.args ? zend_hash_num_elements(
type->func.args) : 0;
2199 func->internal_function.handler =
ZEND_FN(ffi_trampoline);
2200 func->internal_function.module =
NULL;
2201 func->internal_function.doc_comment =
NULL;
2203 func->internal_function.reserved[0] =
type;
2204 func->internal_function.reserved[1] = *(
void**)
cdata->ptr;
2220 zend_ffi_object_init(&
ctype->std, class_type);
2228static void zend_ffi_ctype_free_obj(
zend_object *
object)
2232 zend_ffi_type_dtor(
ctype->type);
2256 type1->array.length ==
type2->array.length) {
2278static int zend_ffi_ctype_compare_objects(
zval *o1,
zval *o2)
2293 zend_throw_error(zend_ffi_exception_ce,
"Comparison of incompatible C types");
2310 zend_ffi_object_init(&
ffi->std, class_type);
2315 ffi->persistent = 0;
2325 switch (
type->kind) {
2327 if (
type->enumeration.tag_name) {
2328 zend_string_release(
type->enumeration.tag_name);
2332 if (
type->record.tag_name) {
2333 zend_string_release(
type->record.tag_name);
2338 zend_ffi_type_dtor(
type->pointer.type);
2341 zend_ffi_type_dtor(
type->array.type);
2344 if (
type->func.args) {
2348 zend_ffi_type_dtor(
type->func.ret_type);
2357static void zend_ffi_type_hash_dtor(
zval *
zv)
2360 zend_ffi_type_dtor(
type);
2364static void zend_ffi_field_hash_dtor(
zval *
zv)
2367 zend_ffi_type_dtor(field->type);
2372static void zend_ffi_field_hash_persistent_dtor(
zval *
zv)
2375 zend_ffi_type_dtor(field->type);
2380static void zend_ffi_symbol_hash_dtor(
zval *
zv)
2383 zend_ffi_type_dtor(sym->
type);
2388static void zend_ffi_symbol_hash_persistent_dtor(
zval *
zv)
2391 zend_ffi_type_dtor(sym->
type);
2396static void zend_ffi_tag_hash_dtor(
zval *
zv)
2399 zend_ffi_type_dtor(tag->
type);
2404static void zend_ffi_tag_hash_persistent_dtor(
zval *
zv)
2407 zend_ffi_type_dtor(tag->
type);
2414 zend_ffi_type_dtor(
cdata->type);
2416 if (
cdata->ptr != (
void*)&
cdata->ptr_holder) {
2425static void zend_ffi_scope_hash_dtor(
zval *
zv)
2428 if (
scope->symbols) {
2430 free(
scope->symbols);
2444 if (
ffi->persistent) {
2449 DL_UNLOAD(
ffi->lib);
2469static void zend_ffi_cdata_free_obj(
zend_object *
object)
2473 zend_ffi_cdata_dtor(
cdata);
2489 new_cdata->std.handlers = &zend_ffi_cdata_value_handlers;
2513 return &
EG(uninitialized_zval);
2529 zend_ffi_object_init(&
cdata->std, zend_ffi_cdata_ce);
2582 *pass_type = &ffi_type_float;
2583 *(
float*)arg_values[
n] = (
float)
dval;
2587 *pass_type = &ffi_type_double;
2588 *(
double*)arg_values[
n] =
dval;
2590#ifdef HAVE_LONG_DOUBLE
2591 case ZEND_FFI_TYPE_LONGDOUBLE:
2593 *pass_type = &ffi_type_double;
2594 *(
long double*)arg_values[
n] = (
long double)
dval;
2598 lval = zval_get_long(
arg);
2599 *pass_type = &ffi_type_uint8;
2600 *(uint8_t*)arg_values[
n] = (uint8_t)lval;
2603 lval = zval_get_long(
arg);
2604 *pass_type = &ffi_type_sint8;
2605 *(int8_t*)arg_values[
n] = (int8_t)lval;
2608 lval = zval_get_long(
arg);
2609 *pass_type = &ffi_type_uint16;
2610 *(uint16_t*)arg_values[
n] = (uint16_t)lval;
2613 lval = zval_get_long(
arg);
2614 *pass_type = &ffi_type_sint16;
2615 *(int16_t*)arg_values[
n] = (int16_t)lval;
2618 lval = zval_get_long(
arg);
2619 *pass_type = &ffi_type_uint32;
2620 *(uint32_t*)arg_values[
n] = (uint32_t)lval;
2623 lval = zval_get_long(
arg);
2624 *pass_type = &ffi_type_sint32;
2625 *(int32_t*)arg_values[
n] = (int32_t)lval;
2628 lval = zval_get_long(
arg);
2629 *pass_type = &ffi_type_uint64;
2630 *(uint64_t*)arg_values[
n] = (uint64_t)lval;
2633 lval = zval_get_long(
arg);
2634 *pass_type = &ffi_type_sint64;
2635 *(int64_t*)arg_values[
n] = (int64_t)lval;
2638 *pass_type = &ffi_type_pointer;
2640 *(
void**)arg_values[
n] =
NULL;
2656 *(
void**)arg_values[
n] = *(
void**)
cdata->ptr;
2658 *(
void**)arg_values[
n] =
cdata->ptr;
2677 *pass_type = &ffi_type_uint8;
2681 str = zval_get_tmp_string(
arg, &tmp_str);
2682 *pass_type = &ffi_type_sint8;
2683 *(
char*)arg_values[
n] =
ZSTR_VAL(str)[0];
2687 zend_tmp_string_release(tmp_str);
2697 *pass_type = zend_ffi_make_fake_struct_type(
type);
2698 arg_values[
n] =
cdata->ptr;
2705 zend_ffi_pass_unsupported(
type);
2717 *pass_type = &ffi_type_pointer;
2718 *(
void**)arg_values[
n] =
NULL;
2721 *pass_type = &ffi_type_uint8;
2722 *(uint8_t*)arg_values[
n] = 0;
2725 *pass_type = &ffi_type_uint8;
2726 *(uint8_t*)arg_values[
n] = 1;
2730 *pass_type = &ffi_type_sint32;
2733 *pass_type = &ffi_type_sint64;
2738 *pass_type = &ffi_type_double;
2742 *pass_type = &ffi_type_pointer;
2764 void *
addr =
EX(
func)->internal_function.reserved[1];
2766 ffi_type *ret_type =
NULL;
2767 ffi_type **arg_types =
NULL;
2768 void **arg_values =
NULL;
2769 uint32_t
n, arg_count;
2780 zend_throw_error(zend_ffi_exception_ce,
"Incorrect number of arguments for C function '%s', expecting at least %d parameter%s",
ZSTR_VAL(
EX(
func)->internal_function.function_name), arg_count, (arg_count != 1) ?
"s" :
"");
2785 sizeof(ffi_type*) *
EX_NUM_ARGS(), arg_types_use_heap);
2789 if (
type->func.args) {
2812 zend_ffi_return_unsupported(
type->func.ret_type);
2817 if (ffi_prep_cif_var(&cif,
type->func.abi, arg_count,
EX_NUM_ARGS(), ret_type, arg_types) != FFI_OK) {
2825 zend_throw_error(zend_ffi_exception_ce,
"Incorrect number of arguments for C function '%s', expecting exactly %d parameter%s",
ZSTR_VAL(
EX(
func)->internal_function.function_name), arg_count, (arg_count != 1) ?
"s" :
"");
2830 (
sizeof(ffi_type*) +
sizeof(ffi_type)) *
EX_NUM_ARGS(), arg_types_use_heap);
2834 if (
type->func.args) {
2849 zend_ffi_return_unsupported(
type->func.ret_type);
2854 if (ffi_prep_cif(&cif,
type->func.abi, arg_count, ret_type, arg_types) != FFI_OK) {
2863 ffi_call(&cif,
addr,
ret, arg_values);
2865 for (
n = 0;
n < arg_count;
n++) {
2866 if (arg_types[
n]->
type == FFI_TYPE_STRUCT) {
2870 if (ret_type->type == FFI_TYPE_STRUCT) {
2882#ifdef WORDS_BIGENDIAN
2883 if (func_ret_type->
size <
sizeof(ffi_arg)
2888 switch (func_ret_type->
size) {
2890 *(uint8_t*)
ret = *(ffi_arg*)
ret;
2893 *(uint16_t*)
ret = *(ffi_arg*)
ret;
2896 *(uint32_t*)
ret = *(ffi_arg*)
ret;
2911 zend_string_release(
EX(
func)->common.function_name);
2946 sym = zend_hash_find_ptr(
ffi->symbols,
name);
2965 func->common.arg_flags[0] = 0;
2966 func->common.arg_flags[1] = 0;
2967 func->common.arg_flags[2] = 0;
2969 func->common.function_name = zend_string_copy(
name);
2971 func->common.num_args = 0;
2972 func->common.required_num_args =
type->func.args ? zend_hash_num_elements(
type->func.args) : 0;
2976 func->internal_function.handler =
ZEND_FN(ffi_trampoline);
2977 func->internal_function.module =
NULL;
2978 func->internal_function.doc_comment =
NULL;
2980 func->internal_function.reserved[0] =
type;
2981 func->internal_function.reserved[1] = sym->
addr;
2987static int zend_fake_compare_objects(
zval *o1,
zval *o2)
2995 zend_throw_error(zend_ffi_exception_ce,
"FFI API is restricted by \"ffi.enable\" configuration directive");
3013 return zend_ffi_disabled();
3017#define ZEND_FFI_VALIDATE_API_RESTRICTION() do { \
3018 if (UNEXPECTED(!zend_ffi_validate_api_restriction(execute_data))) { \
3042 err = GET_DL_ERROR();
3101 zend_string_release(mangled_name);
3137 switch (old->
kind) {
3146 if (zend_hash_num_elements(&old->
record.
fields) != zend_hash_num_elements(&
type->record.fields)) {
3159 || !zend_string_equals(
key, b->
key)) {
3162 }
else if (b->
key) {
3166 if (old_field->
offset != field->offset
3167 || old_field->
is_const != field->is_const
3168 || old_field->
is_nested != field->is_nested
3169 || old_field->
first_bit != field->first_bit
3170 || old_field->
bits != field->bits
3180 || ((old->
func.
args ? zend_hash_num_elements(old->
func.
args) : 0) != (
type->func.args ? zend_hash_num_elements(
type->func.args) : 0))
3242 switch (dcl_type->
kind) {
3246 return zend_ffi_subst_old_type(&dcl_type->
array.
type, old,
type);
3263 if (zend_ffi_subst_old_type(&field->type, old,
type)) {
3281 zend_ffi_subst_old_type(&sym->
type, old,
type);
3286 zend_ffi_subst_old_type(&tag->
type, old,
type);
3309 char *code, *code_pos, *scope_name, *
lib, *
err;
3310 size_t code_size, scope_name_len;
3319 if (
stat(filename, &
buf) != 0) {
3323 zend_throw_error(zend_ffi_exception_ce,
"Failed loading '%s', file doesn't exist", filename);
3328 if ((
buf.st_mode & S_IFMT) != S_IFREG) {
3332 zend_throw_error(zend_ffi_exception_ce,
"Failed loading '%s', not a regular file", filename);
3337 code_size =
buf.st_size;
3338 code =
emalloc(code_size + 1);
3339 int open_flags = O_RDONLY;
3341 open_flags |= _O_BINARY;
3343 fd = open(filename, open_flags, 0);
3344 if (
fd < 0 || read(
fd, code, code_size) != code_size) {
3348 zend_throw_error(zend_ffi_exception_ce,
"Failed loading '%s', cannot read_file", filename);
3355 code[code_size] = 0;
3367 code_pos = zend_ffi_parse_directives(filename, code, &scope_name, &
lib,
preload);
3373 code_size -= code_pos - code;
3390 err = GET_DL_ERROR();
3416 scope_name_len =
strlen(scope_name);
3442 zend_string_release(mangled_name);
3460 if (zend_ffi_same_symbols(old_sym, sym)) {
3465 zend_ffi_type_dtor(
type);
3485 if (zend_ffi_same_tags(old_tag, tag)) {
3490 zend_ffi_type_dtor(
type);
3516 if (!
scope->symbols) {
3521 if (!zend_hash_add_ptr(
scope->symbols,
name, sym)) {
3522 zend_ffi_type_dtor(sym->
type);
3536 if (!zend_hash_add_ptr(
scope->tags,
name, tag)) {
3537 zend_ffi_type_dtor(tag->
type);
3547 if (
EG(objects_store).object_buckets) {
3554 ffi->persistent = 1;
3597 zend_throw_error(zend_ffi_exception_ce,
"FFI::load() doesn't work in conjunction with \"opcache.preload_user\". Use \"ffi.preload\" instead.");
3642 zend_ffi_type_dtor(
dcl->type);
3648static void zend_ffi_throw_parser_error(
const char *format, ...)
3651 char *message =
NULL;
3653 va_start(va, format);
3656 if (
EG(current_execute_data)) {
3670 zend_ffi_throw_parser_error(
"\"[*]\" is not allowed in other than function prototype scope at line %d",
FFI_G(
line));
3691 zend_ffi_throw_parser_error(
"Incomplete struct \"%s\" at line %d",
ZSTR_VAL(
key),
FFI_G(
line));
3708 zend_ffi_throw_parser_error(
"Incomplete type at line %d",
FFI_G(
line));
3711 zend_ffi_throw_parser_error(
"\"[]\" is not allowed at line %d",
FFI_G(
line));
3714 zend_ffi_throw_parser_error(
"\"[*]\" is not allowed in other than function prototype scope at line %d",
FFI_G(
line));
3724 zend_ffi_throw_parser_error(
"void type is not allowed at line %d",
FFI_G(
line));
3727 return zend_ffi_validate_incomplete_type(
type, allow_incomplete_tag, allow_incomplete_array);
3734 zend_ffi_throw_parser_error(
"function type is not allowed at line %d",
FFI_G(
line));
3737 return zend_ffi_validate_type(
type, 0, allow_incomplete_array);
3743 zend_ffi_finalize_type(
dcl);
3761 switch (dcl_type->
kind) {
3782 if (zend_ffi_subst_type(&field->type,
type)) {
3799 zend_ffi_subst_type(&
dcl->type,
type);
3861 zend_ffi_type_dtor(
dcl.type);
3881 zend_ffi_tags_cleanup(&
dcl);
3910 zend_throw_error(zend_ffi_exception_ce,
"Cannot instantiate FFI\\CData of zero size");
3920 cdata->std.handlers = &zend_ffi_cdata_value_handlers;
3947 zend_throw_error(zend_ffi_exception_ce,
"NULL pointer dereference");
3951 pefree(*(void**)cdata->ptr, cdata->flags & ZEND_FFI_FLAG_PERSISTENT);
3953 pefree(cdata->ptr_holder, (cdata->flags & ZEND_FFI_FLAG_PERSISTENT) || !is_zend_ptr(cdata->ptr_holder));
3957 pefree(cdata->ptr, cdata->flags & ZEND_FFI_FLAG_PERSISTENT);
3959 cdata->flags &= ~(ZEND_FFI_FLAG_OWNED|ZEND_FFI_FLAG_PERSISTENT);
3960 cdata->std.handlers = &zend_ffi_cdata_free_handlers;
3962 zend_throw_error(zend_ffi_exception_ce,
"free() non a C pointer");
4011 zend_ffi_type_dtor(
dcl.type);
4031 zend_ffi_tags_cleanup(&
dcl);
4063 cdata->std.handlers = &zend_ffi_cdata_value_handlers;
4104 cdata->std.handlers = &zend_ffi_cdata_value_handlers;
4123 zend_object_release(&
cdata->std);
4183 zend_ffi_type_dtor(
dcl.type);
4198 zend_ffi_tags_cleanup(&
dcl);
4274 zend_throw_error(zend_ffi_exception_ce,
"Array of functions is not allowed");
4277 zend_throw_error(zend_ffi_exception_ce,
"Only the leftmost array can be undimensioned");
4280 zend_throw_error(zend_ffi_exception_ce,
"Array of void type is not allowed");
4283 zend_throw_error(zend_ffi_exception_ce,
"Array of incomplete type is not allowed");
4305 zend_ffi_type_dtor(
type);
4308 zend_throw_error(zend_ffi_exception_ce,
"only the leftmost array can be undimensioned");
4309 zend_ffi_type_dtor(
type);
4358 zend_throw_error(zend_ffi_exception_ce,
"FFI::addr() cannot create a reference to a temporary pointer");
4466 zend_throw_error(zend_ffi_exception_ce,
"Attempt to write over data boundary");
4475 zend_throw_error(zend_ffi_exception_ce,
"Attempt to read over string boundary");
4486 zend_throw_error(zend_ffi_exception_ce,
"Attempt to read over data boundary");
4519 zend_throw_error(zend_ffi_exception_ce,
"attempt to read over string boundary");
4530 zend_throw_error(zend_ffi_exception_ce,
"attempt to read over data boundary");
4543 zend_throw_error(zend_ffi_exception_ce,
"Attempt to read over string boundary");
4554 zend_throw_error(zend_ffi_exception_ce,
"Attempt to read over data boundary");
4566 }
else if (
ret < 0) {
4596 zend_throw_error(zend_ffi_exception_ce,
"attempt to write over data boundary");
4625 ptr = *(void**)cdata->ptr;
4628 if (type->kind != ZEND_FFI_TYPE_POINTER && size > type->size) {
4629 zend_throw_error(zend_ffi_exception_ce,
"attempt to read over data boundary");
4765 zend_throw_error(zend_ffi_exception_ce,
"FFI\\CType is not an enumeration");
4878 ptr = zend_hash_find_ptr(&
type->record.fields,
name);
4905 ptr = zend_hash_find_ptr(&
type->record.fields,
name);
4997 ptr = zend_hash_index_find_ptr(
type->func.args,
n);
5009static char *zend_ffi_skip_ws_and_comments(
char *
p,
bool allow_standalone_newline)
5012 if (*
p ==
' ' || *
p ==
'\t') {
5014 }
else if (allow_standalone_newline && (*
p ==
'\r' || *
p ==
'\n' || *
p ==
'\f' || *
p ==
'\v')) {
5016 }
else if (allow_standalone_newline && *
p ==
'/' &&
p[1] ==
'/') {
5018 while (*
p && *
p !=
'\r' && *
p !=
'\n') {
5021 }
else if (*
p ==
'/' &&
p[1] ==
'*') {
5023 while (*
p && (*
p !=
'*' ||
p[1] !=
'/')) {
5040static char *zend_ffi_parse_directives(
const char *filename,
char *code_pos,
char **scope_name,
char **
lib,
bool preload)
5044 code_pos = zend_ffi_skip_ws_and_comments(code_pos,
true);
5048 while (*code_pos ==
'#') {
5050 p = zend_ffi_skip_ws_and_comments(code_pos +
sizeof(
"#define") - 1,
false);
5052 char **target =
NULL;
5053 const char *target_name =
NULL;
5055 p = zend_ffi_skip_ws_and_comments(
p +
sizeof(
"FFI_SCOPE") - 1,
false);
5056 target = scope_name;
5057 target_name =
"FFI_SCOPE";
5059 p = zend_ffi_skip_ws_and_comments(
p +
sizeof(
"FFI_LIB") - 1,
false);
5061 target_name =
"FFI_LIB";
5063 while (*
p && *
p !=
'\n' && *
p !=
'\r') {
5066 code_pos = zend_ffi_skip_ws_and_comments(
p,
true);
5072 zend_error(
E_WARNING,
"FFI: failed pre-loading '%s', bad %s define", filename, target_name);
5074 zend_throw_error(zend_ffi_exception_ce,
"Failed loading '%s', bad %s define", filename, target_name);
5081 zend_error(
E_WARNING,
"FFI: failed pre-loading '%s', %s defined twice", filename, target_name);
5083 zend_throw_error(zend_ffi_exception_ce,
"Failed loading '%s', %s defined twice", filename, target_name);
5093 }
else if (*
p <=
' ') {
5095 zend_error(
E_WARNING,
"FFI: failed pre-loading '%s', bad %s define", filename, target_name);
5097 zend_throw_error(zend_ffi_exception_ce,
"Failed loading '%s', bad %s define", filename, target_name);
5104 code_pos = zend_ffi_skip_ws_and_comments(
p,
true);
5128 zend_bad_array_access(obj->
ce);
5135 zend_bad_array_access(obj->
ce);
5141 zend_bad_array_access(obj->
ce);
5148 zend_bad_array_access(obj->
ce);
5160 zend_bad_property_access(obj->
ce);
5161 return &
EG(uninitialized_zval);
5167 zend_bad_array_access(obj->
ce);
5174 zend_bad_array_access(obj->
ce);
5181 zend_bad_array_access(obj->
ce);
5232 zend_ffi_use_after_free();
5239 zend_ffi_use_after_free();
5246 zend_ffi_use_after_free();
5252 zend_ffi_use_after_free();
5259 zend_ffi_use_after_free();
5265 zend_ffi_use_after_free();
5266 return &
EG(uninitialized_zval);
5272 zend_ffi_use_after_free();
5279 zend_ffi_use_after_free();
5286 zend_ffi_use_after_free();
5292 zend_ffi_use_after_free();
5325static
zend_result zend_ffi_preload_glob(const
char *filename)
5342 for(i=0 ; i<globbuf.
gl_pathc; i++) {
5367 char *
s =
NULL, *e, *filename;
5378 ffi = zend_ffi_load(filename, 1);
5411 ffi = zend_ffi_load(filename, 1);
5439 ++zend_ffi_new_fn.T;
5440 ++zend_ffi_cast_fn.T;
5441 ++zend_ffi_type_fn.T;
5448 if (prev_zend_post_startup_cb) {
5449 return prev_zend_post_startup_cb();
5461 zend_ffi_exception_ce = register_class_FFI_Exception(
zend_ce_error);
5463 zend_ffi_parser_exception_ce = register_class_FFI_ParserException(zend_ffi_exception_ce);
5465 zend_ffi_ce = register_class_FFI();
5466 zend_ffi_ce->create_object = zend_ffi_new;
5467 zend_ffi_ce->default_object_handlers = &zend_ffi_handlers;
5469 memcpy(&zend_ffi_new_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table,
"new",
sizeof(
"new")-1),
sizeof(
zend_internal_function));
5471 memcpy(&zend_ffi_cast_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table,
"cast",
sizeof(
"cast")-1),
sizeof(
zend_internal_function));
5473 memcpy(&zend_ffi_type_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table,
"type",
sizeof(
"type")-1),
sizeof(
zend_internal_function));
5480 zend_ffi_handlers.get_constructor = zend_fake_get_constructor;
5481 zend_ffi_handlers.free_obj = zend_ffi_free_obj;
5482 zend_ffi_handlers.clone_obj =
NULL;
5483 zend_ffi_handlers.read_property = zend_ffi_read_var;
5484 zend_ffi_handlers.write_property = zend_ffi_write_var;
5485 zend_ffi_handlers.read_dimension = zend_fake_read_dimension;
5486 zend_ffi_handlers.write_dimension = zend_fake_write_dimension;
5487 zend_ffi_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr;
5488 zend_ffi_handlers.has_property = zend_fake_has_property;
5489 zend_ffi_handlers.unset_property = zend_fake_unset_property;
5490 zend_ffi_handlers.has_dimension = zend_fake_has_dimension;
5491 zend_ffi_handlers.unset_dimension = zend_fake_unset_dimension;
5492 zend_ffi_handlers.get_method = zend_ffi_get_func;
5493 zend_ffi_handlers.compare = zend_fake_compare_objects;
5494 zend_ffi_handlers.cast_object = zend_fake_cast_object;
5495 zend_ffi_handlers.get_debug_info =
NULL;
5496 zend_ffi_handlers.get_closure =
NULL;
5497 zend_ffi_handlers.get_properties = zend_fake_get_properties;
5498 zend_ffi_handlers.get_gc = zend_fake_get_gc;
5500 zend_ffi_cdata_ce = register_class_FFI_CData();
5501 zend_ffi_cdata_ce->create_object = zend_ffi_cdata_new;
5502 zend_ffi_cdata_ce->default_object_handlers = &zend_ffi_cdata_handlers;
5503 zend_ffi_cdata_ce->get_iterator = zend_ffi_cdata_get_iterator;
5506 zend_ffi_cdata_handlers.get_constructor = zend_fake_get_constructor;
5507 zend_ffi_cdata_handlers.free_obj = zend_ffi_cdata_free_obj;
5508 zend_ffi_cdata_handlers.clone_obj = zend_ffi_cdata_clone_obj;
5509 zend_ffi_cdata_handlers.read_property = zend_ffi_cdata_read_field;
5510 zend_ffi_cdata_handlers.write_property = zend_ffi_cdata_write_field;
5511 zend_ffi_cdata_handlers.read_dimension = zend_ffi_cdata_read_dim;
5512 zend_ffi_cdata_handlers.write_dimension = zend_ffi_cdata_write_dim;
5513 zend_ffi_cdata_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr;
5514 zend_ffi_cdata_handlers.has_property = zend_fake_has_property;
5515 zend_ffi_cdata_handlers.unset_property = zend_fake_unset_property;
5516 zend_ffi_cdata_handlers.has_dimension = zend_fake_has_dimension;
5517 zend_ffi_cdata_handlers.unset_dimension = zend_fake_unset_dimension;
5518 zend_ffi_cdata_handlers.get_method = zend_fake_get_method;
5519 zend_ffi_cdata_handlers.get_class_name = zend_ffi_cdata_get_class_name;
5520 zend_ffi_cdata_handlers.do_operation = zend_ffi_cdata_do_operation;
5521 zend_ffi_cdata_handlers.compare = zend_ffi_cdata_compare_objects;
5522 zend_ffi_cdata_handlers.cast_object = zend_ffi_cdata_cast_object;
5523 zend_ffi_cdata_handlers.count_elements = zend_ffi_cdata_count_elements;
5524 zend_ffi_cdata_handlers.get_debug_info = zend_ffi_cdata_get_debug_info;
5525 zend_ffi_cdata_handlers.get_closure = zend_ffi_cdata_get_closure;
5526 zend_ffi_cdata_handlers.get_properties = zend_fake_get_properties;
5527 zend_ffi_cdata_handlers.get_gc = zend_fake_get_gc;
5530 zend_ffi_cdata_value_handlers.get_constructor = zend_fake_get_constructor;
5531 zend_ffi_cdata_value_handlers.free_obj = zend_ffi_cdata_free_obj;
5532 zend_ffi_cdata_value_handlers.clone_obj = zend_ffi_cdata_clone_obj;
5533 zend_ffi_cdata_value_handlers.read_property = zend_ffi_cdata_get;
5534 zend_ffi_cdata_value_handlers.write_property = zend_ffi_cdata_set;
5535 zend_ffi_cdata_value_handlers.read_dimension = zend_fake_read_dimension;
5536 zend_ffi_cdata_value_handlers.write_dimension = zend_fake_write_dimension;
5537 zend_ffi_cdata_value_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr;
5538 zend_ffi_cdata_value_handlers.has_property = zend_fake_has_property;
5539 zend_ffi_cdata_value_handlers.unset_property = zend_fake_unset_property;
5540 zend_ffi_cdata_value_handlers.has_dimension = zend_fake_has_dimension;
5541 zend_ffi_cdata_value_handlers.unset_dimension = zend_fake_unset_dimension;
5542 zend_ffi_cdata_value_handlers.get_method = zend_fake_get_method;
5543 zend_ffi_cdata_value_handlers.get_class_name = zend_ffi_cdata_get_class_name;
5544 zend_ffi_cdata_value_handlers.compare = zend_ffi_cdata_compare_objects;
5545 zend_ffi_cdata_value_handlers.cast_object = zend_ffi_cdata_cast_object;
5546 zend_ffi_cdata_value_handlers.count_elements =
NULL;
5547 zend_ffi_cdata_value_handlers.get_debug_info = zend_ffi_cdata_get_debug_info;
5548 zend_ffi_cdata_value_handlers.get_closure =
NULL;
5549 zend_ffi_cdata_value_handlers.get_properties = zend_fake_get_properties;
5550 zend_ffi_cdata_value_handlers.get_gc = zend_fake_get_gc;
5553 zend_ffi_cdata_free_handlers.get_constructor = zend_fake_get_constructor;
5554 zend_ffi_cdata_free_handlers.free_obj = zend_ffi_cdata_free_obj;
5555 zend_ffi_cdata_free_handlers.clone_obj = zend_ffi_free_clone_obj;
5556 zend_ffi_cdata_free_handlers.read_property = zend_ffi_free_read_property;
5557 zend_ffi_cdata_free_handlers.write_property = zend_ffi_free_write_property;
5558 zend_ffi_cdata_free_handlers.read_dimension = zend_ffi_free_read_dimension;
5559 zend_ffi_cdata_free_handlers.write_dimension = zend_ffi_free_write_dimension;
5560 zend_ffi_cdata_free_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr;
5561 zend_ffi_cdata_free_handlers.has_property = zend_ffi_free_has_property;
5562 zend_ffi_cdata_free_handlers.unset_property = zend_ffi_free_unset_property;
5563 zend_ffi_cdata_free_handlers.has_dimension = zend_ffi_free_has_dimension;
5564 zend_ffi_cdata_free_handlers.unset_dimension = zend_ffi_free_unset_dimension;
5565 zend_ffi_cdata_free_handlers.get_method = zend_fake_get_method;
5566 zend_ffi_cdata_free_handlers.get_class_name = zend_ffi_cdata_get_class_name;
5567 zend_ffi_cdata_free_handlers.compare = zend_ffi_cdata_compare_objects;
5568 zend_ffi_cdata_free_handlers.cast_object = zend_fake_cast_object;
5569 zend_ffi_cdata_free_handlers.count_elements =
NULL;
5570 zend_ffi_cdata_free_handlers.get_debug_info = zend_ffi_free_get_debug_info;
5571 zend_ffi_cdata_free_handlers.get_closure =
NULL;
5572 zend_ffi_cdata_free_handlers.get_properties = zend_fake_get_properties;
5573 zend_ffi_cdata_free_handlers.get_gc = zend_fake_get_gc;
5575 zend_ffi_ctype_ce = register_class_FFI_CType();
5576 zend_ffi_ctype_ce->create_object = zend_ffi_ctype_new;
5577 zend_ffi_ctype_ce->default_object_handlers = &zend_ffi_ctype_handlers;
5580 zend_ffi_ctype_handlers.get_constructor = zend_fake_get_constructor;
5581 zend_ffi_ctype_handlers.free_obj = zend_ffi_ctype_free_obj;
5582 zend_ffi_ctype_handlers.clone_obj =
NULL;
5583 zend_ffi_ctype_handlers.read_property = zend_fake_read_property;
5584 zend_ffi_ctype_handlers.write_property = zend_fake_write_property;
5585 zend_ffi_ctype_handlers.read_dimension = zend_fake_read_dimension;
5586 zend_ffi_ctype_handlers.write_dimension = zend_fake_write_dimension;
5587 zend_ffi_ctype_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr;
5588 zend_ffi_ctype_handlers.has_property = zend_fake_has_property;
5589 zend_ffi_ctype_handlers.unset_property = zend_fake_unset_property;
5590 zend_ffi_ctype_handlers.has_dimension = zend_fake_has_dimension;
5591 zend_ffi_ctype_handlers.unset_dimension = zend_fake_unset_dimension;
5593 zend_ffi_ctype_handlers.get_class_name = zend_ffi_ctype_get_class_name;
5594 zend_ffi_ctype_handlers.compare = zend_ffi_ctype_compare_objects;
5595 zend_ffi_ctype_handlers.cast_object = zend_fake_cast_object;
5596 zend_ffi_ctype_handlers.count_elements =
NULL;
5597 zend_ffi_ctype_handlers.get_debug_info = zend_ffi_ctype_get_debug_info;
5598 zend_ffi_ctype_handlers.get_closure =
NULL;
5599 zend_ffi_ctype_handlers.get_properties = zend_fake_get_properties;
5600 zend_ffi_ctype_handlers.get_gc = zend_fake_get_gc;
5655#ifdef HAVE_LONG_DOUBLE
5656static const zend_ffi_type zend_ffi_type_long_double = {.kind=ZEND_FFI_TYPE_LONGDOUBLE, .size=
sizeof(
long double), .
align=_Alignof(
long double)};
5661static const struct {
5664} zend_ffi_types[] = {
5665 {
"void", &zend_ffi_type_void},
5666 {
"char", &zend_ffi_type_char},
5667 {
"bool", &zend_ffi_type_bool},
5668 {
"int8_t", &zend_ffi_type_sint8},
5669 {
"uint8_t", &zend_ffi_type_uint8},
5670 {
"int16_t", &zend_ffi_type_sint16},
5671 {
"uint16_t", &zend_ffi_type_uint16},
5672 {
"int32_t", &zend_ffi_type_sint32},
5673 {
"uint32_t", &zend_ffi_type_uint32},
5674 {
"int64_t", &zend_ffi_type_sint64},
5675 {
"uint64_t", &zend_ffi_type_uint64},
5676 {
"float", &zend_ffi_type_float},
5677 {
"double", &zend_ffi_type_double},
5678#ifdef HAVE_LONG_DOUBLE
5679 {
"long double", &zend_ffi_type_long_double},
5681#if SIZEOF_SIZE_T == 4
5682 {
"uintptr_t", &zend_ffi_type_uint32},
5683 {
"intptr_t", &zend_ffi_type_sint32},
5684 {
"size_t", &zend_ffi_type_uint32},
5685 {
"ssize_t", &zend_ffi_type_sint32},
5686 {
"ptrdiff_t", &zend_ffi_type_sint32},
5688 {
"uintptr_t", &zend_ffi_type_uint64},
5689 {
"intptr_t", &zend_ffi_type_sint64},
5690 {
"size_t", &zend_ffi_type_uint64},
5691 {
"ssize_t", &zend_ffi_type_sint64},
5692 {
"ptrdiff_t", &zend_ffi_type_sint64},
5694#if SIZEOF_OFF_T == 4
5695 {
"off_t", &zend_ffi_type_sint32},
5697 {
"off_t", &zend_ffi_type_sint64},
5700 {
"va_list", &zend_ffi_type_ptr},
5701 {
"__builtin_va_list", &zend_ffi_type_ptr},
5702 {
"__gnuc_va_list", &zend_ffi_type_ptr},
5710#if defined(COMPILE_DL_FFI) && defined(ZTS)
5713 memset(ffi_globals, 0,
sizeof(*ffi_globals));
5715 for (i = 0; i <
sizeof(zend_ffi_types)/
sizeof(zend_ffi_types[0]); i++) {
5716 zend_hash_str_add_new_ptr(&ffi_globals->types, zend_ffi_types[i].name,
strlen(zend_ffi_types[i].
name), (
void*)zend_ffi_types[i].
type);
5724 if (ffi_globals->scopes) {
5726 free(ffi_globals->scopes);
5751#ifdef COMPILE_DL_FFI
5762 char *message =
NULL;
5764 va_start(va, format);
5767 if (
EG(current_execute_data)) {
5820 if (
sizeof(
long) == 4) {
5828 if (
sizeof(
long) == 4) {
5922 val->len = name_len;
5962 type->size = zend_ffi_type_uint8.size;
5963 type->align = zend_ffi_type_uint8.align;
5966 type->size = zend_ffi_type_uint32.size;
5967 type->align = zend_ffi_type_uint32.align;
5991 if (*
last == 0x7FFFFFFFFFFFFFFFLL) {
5995 if ((*
min != 0 || *
max != 0)
5996 && (uint64_t)*
last == 0xFFFFFFFFFFFFFFFFULL) {
6002 if (!is_signed &&
val->ch < 0) {
6003 if ((uint64_t)*
max > 0x7FFFFFFFFFFFFFFFULL) {
6011 if (!is_signed &&
val->i64 < 0) {
6012 if ((uint64_t)*
max > 0x7FFFFFFFFFFFFFFFULL) {
6020 if (is_signed &&
val->u64 > 0x7FFFFFFFFFFFFFFFULL) {
6038 && *
min >= -0x7FLL-1 && *
max <= 0x7FLL) {
6039 sym_type = &zend_ffi_type_sint8;
6041 && *
min >= -0x7FFFLL-1 && *
max <= 0x7FFFLL) {
6042 sym_type = &zend_ffi_type_sint16;
6043 }
else if (*
min >= -0x7FFFFFFFLL-1 && *
max <= 0x7FFFFFFFLL) {
6044 sym_type = &zend_ffi_type_sint32;
6046 sym_type = &zend_ffi_type_sint64;
6052 && (uint64_t)*
max <= 0xFFULL) {
6053 sym_type = &zend_ffi_type_uint8;
6055 && (uint64_t)*
max <= 0xFFFFULL) {
6056 sym_type = &zend_ffi_type_uint16;
6057 }
else if ((uint64_t)*
max <= 0xFFFFFFFFULL) {
6058 sym_type = &zend_ffi_type_uint32;
6060 sym_type = &zend_ffi_type_uint64;
6091 type->align =
dcl->align > 1 ?
dcl->align : 1;
6105 if (zend_hash_num_elements(&struct_type->
record.
fields) > 0) {
6112 zend_ffi_throw_parser_error(
"Flexible array member not at end of struct at line %d",
FFI_G(
line));
6122 if (
type == struct_type) {
6123 zend_ffi_throw_parser_error(
"Struct/union can't contain an instance of itself at line %d",
FFI_G(
line));
6125 }
else if (zend_ffi_validate_var_type(
type, 1) ==
FAILURE) {
6129 zend_ffi_throw_parser_error(
"Flexible array member in union at line %d",
FFI_G(
line));
6133 return zend_ffi_validate_prev_field_type(struct_type);
6144 zend_ffi_finalize_type(field_dcl);
6146 if (zend_ffi_validate_field_type(field_type, struct_type) ==
FAILURE) {
6160 uint32_t field_align =
MAX(field_type->
align, field_dcl->
align);
6161 struct_type->
size = ((struct_type->
size + (field_align - 1)) / field_align) * field_align;
6163 field->offset = struct_type->
size;
6164 struct_type->
size += field_type->
size;
6166 field->type = field_dcl->
type;
6168 field->is_nested = 0;
6169 field->first_bit = 0;
6171 field_dcl->
type = field_type;
6173 if (!zend_hash_str_add_ptr(&struct_type->
record.
fields,
name, name_len, field)) {
6174 zend_ffi_type_dtor(field->type);
6189 zend_ffi_finalize_type(field_dcl);
6201 if (zend_ffi_validate_prev_field_type(struct_type) ==
FAILURE) {
6206 uint32_t field_align =
MAX(field_type->
align, field_dcl->
align);
6207 struct_type->
size = ((struct_type->
size + (field_align - 1)) / field_align) * field_align;
6215 new_field->
offset = field->offset;
6217 new_field->
offset = struct_type->
size + field->offset;
6220 new_field->
is_const = field->is_const;
6222 new_field->
first_bit = field->first_bit;
6223 new_field->
bits = field->bits;
6227 if (!zend_hash_add_ptr(&struct_type->
record.
fields,
key, new_field)) {
6228 zend_ffi_type_dtor(new_field->
type);
6234 zend_hash_next_index_insert_ptr(&struct_type->
record.
fields, field);
6241 struct_type->
size += field_type->
size;
6244 zend_ffi_type_dtor(field_dcl->
type);
6256 zend_ffi_finalize_type(field_dcl);
6258 if (zend_ffi_validate_field_type(field_type, struct_type) ==
FAILURE) {
6269 if (bits->
i64 < 0) {
6272 }
else if (bits->
i64 == 0) {
6278 }
else if (bits->
i64 > field_type->
size * 8) {
6283 if (bits->
u64 == 0) {
6289 }
else if (bits->
u64 > field_type->
size * 8) {
6300 struct_type->
align =
MAX(struct_type->
align,
sizeof(uint32_t));
6304 field->first_bit = 0;
6305 field->bits = bits->
u64;
6309 struct_type->
size =
MAX(struct_type->
size, ((bits->
u64 + 31) / 32) * 4);
6314 if (zend_hash_num_elements(&struct_type->
record.
fields) > 0) {
6319 if (prev_field && prev_field->
bits) {
6320 field->offset = prev_field->
offset;
6321 field->first_bit = prev_field->
first_bit + prev_field->
bits;
6322 field->bits = bits->
u64;
6324 field->offset = struct_type->
size;
6325 field->first_bit = 0;
6326 field->bits = bits->
u64;
6329 struct_type->
size = field->offset + ((field->first_bit + field->bits) + 7) / 8;
6331 struct_type->
size = field->offset + (((field->first_bit + field->bits) + 31) / 32) * 4;
6334 field->type = field_dcl->
type;
6336 field->is_nested = 0;
6337 field_dcl->
type = field_type;
6340 if (!zend_hash_str_add_ptr(&struct_type->
record.
fields,
name, name_len, field)) {
6341 zend_ffi_type_dtor(field->type);
6346 zend_hash_next_index_insert_ptr(&struct_type->
record.
fields, field);
6356 if (
dcl->align > struct_type->
align) {
6360 struct_type->
size = ((struct_type->
size + (struct_type->
align - 1)) / struct_type->
align) * struct_type->
align;
6371 type->size =
sizeof(
void*);
6372 type->align = _Alignof(
void*);
6373 zend_ffi_finalize_type(
dcl);
6378 type->pointer.type =
dcl->type;
6389 zend_ffi_throw_parser_error(
"Array of functions is not allowed at line %d",
FFI_G(
line));
6392 zend_ffi_throw_parser_error(
"Only the leftmost array can be undimensioned at line %d",
FFI_G(
line));
6395 return zend_ffi_validate_type(
type, 0, 1);
6405 zend_ffi_finalize_type(
dcl);
6427 if (zend_ffi_validate_array_element_type(element_type) ==
FAILURE) {
6435 type->size = length * element_type->
size;
6438 type->array.length = length;
6449 zend_ffi_throw_parser_error(
"Function returning function is not allowed at line %d",
FFI_G(
line));
6452 zend_ffi_throw_parser_error(
"Function returning array is not allowed at line %d",
FFI_G(
line));
6455 return zend_ffi_validate_incomplete_type(
type, 1, 0);
6464 zend_ffi_finalize_type(
dcl);
6474 if (zend_hash_num_elements(
args) != 1) {
6493#ifdef HAVE_FFI_VECTORCALL_PARTIAL
6516 if (zend_ffi_validate_func_ret_type(ret_type) ==
FAILURE) {
6529 type->size =
sizeof(
void*);
6531 type->func.ret_type =
dcl->type;
6535 type->func.abi = FFI_DEFAULT_ABI;
6537#ifdef HAVE_FFI_FASTCALL
6539 type->func.abi = FFI_FASTCALL;
6542#ifdef HAVE_FFI_THISCALL
6544 type->func.abi = FFI_THISCALL;
6547#ifdef HAVE_FFI_STDCALL
6549 type->func.abi = FFI_STDCALL;
6552#ifdef HAVE_FFI_PASCAL
6554 type->func.abi = FFI_PASCAL;
6557#ifdef HAVE_FFI_REGISTER
6559 type->func.abi = FFI_REGISTER;
6562#ifdef HAVE_FFI_MS_CDECL
6564 type->func.abi = FFI_MS_CDECL;
6569 type->func.abi = FFI_SYSV;
6572#ifdef HAVE_FFI_VECTORCALL_PARTIAL
6574 type->func.abi = FFI_VECTORCALL_PARTIAL;
6578 type->func.abi = FFI_DEFAULT_ABI;
6585 _zend_ffi_type_dtor(
type);
6605 zend_ffi_finalize_type(arg_dcl);
6610 type->size =
sizeof(
void*);
6629 if (zend_ffi_validate_incomplete_type(
type, 1, 1) ==
FAILURE) {
6636 zend_hash_next_index_insert_ptr(*
args, (
void*)arg_dcl->
type);
6648 zend_ffi_finalize_type(
dcl);
6656 zend_ffi_type_dtor(
dcl->type);
6666 zend_ffi_type_dtor(
dcl->type);
6674 zend_ffi_type_dtor(
dcl->type);
6722 zend_ffi_type_dtor(
dcl->type);
6782 type->record.tag_name = zend_string_copy(tag_name);
6787 type->record.tag_name = zend_string_copy(tag_name);
6792 type->enumeration.tag_name = zend_string_copy(tag_name);
6801 zend_hash_add_new_ptr(
FFI_G(
tags), tag_name, tag);
6802 zend_string_release(tag_name);
6817#define SIMPLE_ATTRIBUTES(_) \
6836 _(warn_unused_result)
6838#define ATTR_ID(name) attr_ ## name,
6839#define ATTR_NAME(name) {sizeof(#name)-1, #name},
6847 static const struct {
6849 const char *
const name;
6859 &&
name[name_len-2] ==
'_'
6860 &&
name[name_len-1] ==
'_') {
6864 for (
id = 0; names[id].len != 0;
id++) {
6865 if (name_len == names[
id].
len) {
6866 if (memcmp(
name, names[
id].
name, name_len) == 0) {
6890 case attr_vectorcall:
6899 case attr_ms_struct:
6902 case attr_gcc_struct:
6905 case attr_unsupported:
6915#define VALUE_ATTRIBUTES(_) \
6930 static const struct {
6932 const char *
const name;
6942 &&
name[name_len-2] ==
'_'
6943 &&
name[name_len-1] ==
'_') {
6947 for (
id = 0; names[id].len != 0;
id++) {
6948 if (name_len == names[
id].
len) {
6949 if (memcmp(
name, names[
id].
name, name_len) == 0) {
6967 &&
val->i64 > 0 &&
val->i64 <= 0x80000000 && (
val->i64 & (
val->i64 - 1)) == 0) {
6976 const char *str =
val->str;
6981 && str[
len-2] ==
'_'
6982 && str[
len-1] ==
'_') {
6988 if (str[1] ==
'I') {
6991 }
else if (str[0] ==
'Q') {
6995 }
else if (str[0] ==
'H') {
6999 }
else if (str[0] ==
'S') {
7003 }
else if (str[0] ==
'D') {
7005 if (
sizeof(
long) == 8) {
7012 }
else if (str[1] ==
'F') {
7015 }
else if (str[0] ==
'S') {
7019 }
else if (str[0] ==
'D') {
7029 case attr_unsupported:
7041 if (name_len ==
sizeof(
"align")-1 && memcmp(
name,
"align",
sizeof(
"align")-1) == 0) {
7043 &&
val->i64 > 0 &&
val->i64 <= 0x80000000 && (
val->i64 & (
val->i64 - 1)) == 0) {
7057 switch (nested_type->
kind) {
7060 if (nested_type->
pointer.
type == &zend_ffi_type_char) {
7069 if (nested_type->
array.
type == &zend_ffi_type_char) {
7085 if (nested_type->
func.
ret_type == &zend_ffi_type_char) {
7101 zend_ffi_finalize_type(
dcl);
7102 if (!nested_dcl->
type || nested_dcl->
type == &zend_ffi_type_char) {
7105 if (zend_ffi_nested_type(
dcl->type, nested_dcl->
type) ==
FAILURE) {
7116 zend_ffi_finalize_type(align_dcl);
7123 switch (align_val->
kind) {
7126 dcl->align = zend_ffi_type_uint32.align;
7130 dcl->align = zend_ffi_type_uint64.align;
7133 dcl->align = zend_ffi_type_float.align;
7136 dcl->align = zend_ffi_type_double.align;
7138#ifdef HAVE_LONG_DOUBLE
7140 dcl->align = zend_ffi_type_long_double.
align;
7145 dcl->align = zend_ffi_type_char.align;
7153#define zend_ffi_expr_bool(val) do { \
7154 if (val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_UINT64) { \
7155 val->kind = ZEND_FFI_VAL_INT32; \
7156 val->i64 = !!val->u64; \
7157 } else if (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_INT64) { \
7158 val->kind = ZEND_FFI_VAL_INT32; \
7159 val->i64 = !!val->i64; \
7160 } else if (val->kind == ZEND_FFI_VAL_FLOAT || val->kind == ZEND_FFI_VAL_DOUBLE || val->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7161 val->kind = ZEND_FFI_VAL_INT32; \
7162 val->i64 = !!val->d; \
7163 } else if (val->kind == ZEND_FFI_VAL_CHAR) { \
7164 val->kind = ZEND_FFI_VAL_INT32; \
7165 val->i64 = !!val->ch; \
7167 val->kind = ZEND_FFI_VAL_ERROR; \
7171#define zend_ffi_expr_math(val, op2, OP) do { \
7172 if (val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_UINT64) { \
7173 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7174 val->kind = MAX(val->kind, op2->kind); \
7175 val->u64 = val->u64 OP op2->u64; \
7176 } else if (op2->kind == ZEND_FFI_VAL_INT32) { \
7177 val->u64 = val->u64 OP op2->i64; \
7178 } else if (op2->kind == ZEND_FFI_VAL_INT64) { \
7179 val->u64 = val->u64 OP op2->i64; \
7180 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7181 val->kind = op2->kind; \
7182 val->d = (zend_ffi_double)val->u64 OP op2->d; \
7183 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7184 val->u64 = val->u64 OP op2->ch; \
7186 val->kind = ZEND_FFI_VAL_ERROR; \
7188 } else if (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_INT64) { \
7189 if (op2->kind == ZEND_FFI_VAL_UINT32) { \
7190 val->i64 = val->i64 OP op2->u64; \
7191 } else if (op2->kind == ZEND_FFI_VAL_UINT64) { \
7192 val->i64 = val->i64 OP op2->u64; \
7193 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7194 val->kind = MAX(val->kind, op2->kind); \
7195 val->i64 = val->i64 OP op2->i64; \
7196 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7197 val->kind = op2->kind; \
7198 val->d = (zend_ffi_double)val->i64 OP op2->d; \
7199 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7200 val->i64 = val->i64 OP op2->ch; \
7202 val->kind = ZEND_FFI_VAL_ERROR; \
7204 } else if (val->kind == ZEND_FFI_VAL_FLOAT || val->kind == ZEND_FFI_VAL_DOUBLE || val->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7205 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7206 val->d = val->d OP (zend_ffi_double)op2->u64; \
7207 } else if (op2->kind == ZEND_FFI_VAL_INT32 ||op2->kind == ZEND_FFI_VAL_INT64) { \
7208 val->d = val->d OP (zend_ffi_double)op2->i64; \
7209 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7210 val->kind = MAX(val->kind, op2->kind); \
7211 val->d = val->d OP op2->d; \
7212 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7213 val->d = val->d OP (zend_ffi_double)op2->ch; \
7215 val->kind = ZEND_FFI_VAL_ERROR; \
7217 } else if (val->kind == ZEND_FFI_VAL_CHAR) { \
7218 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7219 val->kind = op2->kind; \
7220 val->u64 = val->ch OP op2->u64; \
7221 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7222 val->kind = ZEND_FFI_VAL_INT64; \
7223 val->i64 = val->ch OP op2->i64; \
7224 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7225 val->kind = op2->kind; \
7226 val->d = (zend_ffi_double)val->ch OP op2->d; \
7227 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7228 val->ch = val->ch OP op2->ch; \
7230 val->kind = ZEND_FFI_VAL_ERROR; \
7233 val->kind = ZEND_FFI_VAL_ERROR; \
7237#define zend_ffi_expr_int_math(val, op2, OP) do { \
7238 if (val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_UINT64) { \
7239 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7240 val->kind = MAX(val->kind, op2->kind); \
7241 val->u64 = val->u64 OP op2->u64; \
7242 } else if (op2->kind == ZEND_FFI_VAL_INT32) { \
7243 val->u64 = val->u64 OP op2->i64; \
7244 } else if (op2->kind == ZEND_FFI_VAL_INT64) { \
7245 val->u64 = val->u64 OP op2->i64; \
7246 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7247 val->u64 = val->u64 OP (uint64_t)op2->d; \
7248 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7249 val->u64 = val->u64 OP op2->ch; \
7251 val->kind = ZEND_FFI_VAL_ERROR; \
7253 } else if (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_INT64) { \
7254 if (op2->kind == ZEND_FFI_VAL_UINT32) { \
7255 val->i64 = val->i64 OP op2->u64; \
7256 } else if (op2->kind == ZEND_FFI_VAL_UINT64) { \
7257 val->i64 = val->i64 OP op2->u64; \
7258 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7259 val->kind = MAX(val->kind, op2->kind); \
7260 val->i64 = val->i64 OP op2->i64; \
7261 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7262 val->u64 = val->u64 OP (int64_t)op2->d; \
7263 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7264 val->i64 = val->i64 OP op2->ch; \
7266 val->kind = ZEND_FFI_VAL_ERROR; \
7268 } else if (val->kind == ZEND_FFI_VAL_FLOAT || val->kind == ZEND_FFI_VAL_DOUBLE || val->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7269 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7270 val->kind = op2->kind; \
7271 val->u64 = (uint64_t)val->d OP op2->u64; \
7272 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7273 val->kind = op2->kind; \
7274 val->i64 = (int64_t)val->d OP op2->i64; \
7276 val->kind = ZEND_FFI_VAL_ERROR; \
7278 } else if (val->kind == ZEND_FFI_VAL_CHAR) { \
7279 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7280 val->kind = op2->kind; \
7281 val->u64 = (uint64_t)val->ch OP op2->u64; \
7282 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7283 val->kind = op2->kind; \
7284 val->i64 = (int64_t)val->ch OP op2->u64; \
7285 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7286 val->ch = val->ch OP op2->ch; \
7288 val->kind = ZEND_FFI_VAL_ERROR; \
7291 val->kind = ZEND_FFI_VAL_ERROR; \
7295#define zend_ffi_expr_cmp(val, op2, OP) do { \
7296 if (val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_UINT64) { \
7297 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7298 val->kind = ZEND_FFI_VAL_INT32; \
7299 val->i64 = val->u64 OP op2->u64; \
7300 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7301 val->kind = ZEND_FFI_VAL_INT32; \
7302 val->i64 = val->u64 OP op2->u64; \
7303 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7304 val->kind = ZEND_FFI_VAL_INT32; \
7305 val->i64 = (zend_ffi_double)val->u64 OP op2->d; \
7306 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7307 val->kind = ZEND_FFI_VAL_INT32; \
7308 val->i64 = val->u64 OP op2->d; \
7310 val->kind = ZEND_FFI_VAL_ERROR; \
7312 } else if (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_INT64) { \
7313 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7314 val->kind = ZEND_FFI_VAL_INT32; \
7315 val->i64 = val->i64 OP op2->i64; \
7316 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7317 val->kind = ZEND_FFI_VAL_INT32; \
7318 val->i64 = val->i64 OP op2->i64; \
7319 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7320 val->kind = ZEND_FFI_VAL_INT32; \
7321 val->i64 = (zend_ffi_double)val->i64 OP op2->d; \
7322 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7323 val->kind = ZEND_FFI_VAL_INT32; \
7324 val->i64 = val->i64 OP op2->ch; \
7326 val->kind = ZEND_FFI_VAL_ERROR; \
7328 } else if (val->kind == ZEND_FFI_VAL_FLOAT || val->kind == ZEND_FFI_VAL_DOUBLE || val->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7329 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7330 val->kind = ZEND_FFI_VAL_INT32; \
7331 val->i64 = val->d OP (zend_ffi_double)op2->u64; \
7332 } else if (op2->kind == ZEND_FFI_VAL_INT32 ||op2->kind == ZEND_FFI_VAL_INT64) { \
7333 val->kind = ZEND_FFI_VAL_INT32; \
7334 val->i64 = val->d OP (zend_ffi_double)op2->i64; \
7335 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7336 val->kind = ZEND_FFI_VAL_INT32; \
7337 val->i64 = val->d OP op2->d; \
7338 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7339 val->kind = ZEND_FFI_VAL_INT32; \
7340 val->i64 = val->d OP (zend_ffi_double)op2->ch; \
7342 val->kind = ZEND_FFI_VAL_ERROR; \
7344 } else if (val->kind == ZEND_FFI_VAL_CHAR) { \
7345 if (op2->kind == ZEND_FFI_VAL_UINT32 || op2->kind == ZEND_FFI_VAL_UINT64) { \
7346 val->kind = ZEND_FFI_VAL_INT32; \
7347 val->i64 = val->ch OP op2->i64; \
7348 } else if (op2->kind == ZEND_FFI_VAL_INT32 || op2->kind == ZEND_FFI_VAL_INT64) { \
7349 val->kind = ZEND_FFI_VAL_INT32; \
7350 val->i64 = val->ch OP op2->i64; \
7351 } else if (op2->kind == ZEND_FFI_VAL_FLOAT || op2->kind == ZEND_FFI_VAL_DOUBLE || op2->kind == ZEND_FFI_VAL_LONG_DOUBLE) { \
7352 val->kind = ZEND_FFI_VAL_INT32; \
7353 val->i64 = (zend_ffi_double)val->ch OP op2->d; \
7354 } else if (op2->kind == ZEND_FFI_VAL_CHAR) { \
7355 val->kind = ZEND_FFI_VAL_INT32; \
7356 val->i64 = val->ch OP op2->ch; \
7358 val->kind = ZEND_FFI_VAL_ERROR; \
7361 val->kind = ZEND_FFI_VAL_ERROR; \
7500 zend_ffi_finalize_type(
dcl);
7534#ifdef HAVE_LONG_DOUBLE
7535 case ZEND_FFI_TYPE_LONGDOUBLE:
7628 zend_ffi_type_dtor(
dcl->type);
7687 val->u64 = zend_ffi_type_uint32.size;
7690 val->u64 = zend_ffi_type_uint64.size;
7693 val->u64 = zend_ffi_type_float.size;
7696 val->u64 = zend_ffi_type_double.size;
7700 val->u64 = zend_ffi_type_double.size;
7702 val->u64 = zend_ffi_type_long_double.
size;
7706 val->u64 = zend_ffi_type_char.size;
7708 if (memchr(
val->str,
'\\',
val->len)) {
7725 zend_ffi_finalize_type(
dcl);
7729 zend_ffi_type_dtor(
dcl->type);
7737 val->u64 = zend_ffi_type_uint32.align;
7740 val->u64 = zend_ffi_type_uint64.align;
7743 val->u64 = zend_ffi_type_float.align;
7746 val->u64 = zend_ffi_type_double.align;
7747#ifdef HAVE_LONG_DOUBLE
7750 val->u64 = zend_ffi_type_long_double.
align;
7754 val->u64 = zend_ffi_type_char.size;
7757 val->u64 = _Alignof(
char*);
7766 zend_ffi_finalize_type(
dcl);
7769 zend_ffi_type_dtor(
dcl->type);
7778 if (str[str_len-1] ==
'u' || str[str_len-1] ==
'U') {
7780 if (str[str_len-2] ==
'l' || str[str_len-2] ==
'L') {
7782 if (str[str_len-3] ==
'l' || str[str_len-3] ==
'L') {
7786 }
else if (str[str_len-1] ==
'l' || str[str_len-1] ==
'L') {
7788 if (str[str_len-2] ==
'l' || str[str_len-2] ==
'L') {
7790 if (str[str_len-3] ==
'u' || str[str_len-3] ==
'U') {
7793 }
else if (str[str_len-2] ==
'u' || str[str_len-2] ==
'U') {
7798 val->u64 = strtoull(str,
NULL, base);
7801 }
else if (l == 1) {
7803 }
else if (l == 2) {
7810 }
else if (l == 1) {
7812 }
else if (l == 2) {
7822 if (str[str_len-1] ==
'f' || str[str_len-1] ==
'F') {
7824 }
else if (str[str_len-1] ==
'l' || str[str_len-1] ==
'L') {
7834 if (str[0] !=
'\"') {
7839 val->len = str_len - 2;
7848 if (str[0] !=
'\'') {
7854 }
else if (str[1] ==
'\\') {
7855 if (str[2] ==
'a') {
7856 }
else if (str[2] ==
'b' && str_len == 4) {
7858 }
else if (str[2] ==
'f' && str_len == 4) {
7860 }
else if (str[2] ==
'n' && str_len == 4) {
7862 }
else if (str[2] ==
'r' && str_len == 4) {
7864 }
else if (str[2] ==
't' && str_len == 4) {
7866 }
else if (str[2] ==
'v' && str_len == 4) {
7868 }
else if (str[2] >=
'0' && str[2] <=
'7') {
7870 if (str[3] >=
'0' && str[3] <=
'7') {
7871 n =
n * 8 + (str[3] -
'0');
7872 if ((str[4] >=
'0' && str[4] <=
'7') && str_len == 6) {
7873 n =
n * 8 + (str[4] -
'0');
7874 }
else if (str_len != 5) {
7877 }
else if (str_len != 4) {
7885 }
else if (str[2] ==
'x') {
7886 if (str[3] >=
'0' && str[3] <=
'9') {
7888 }
else if (str[3] >=
'A' && str[3] <=
'F') {
7890 }
else if (str[3] >=
'a' && str[3] <=
'f') {
7896 if ((str[4] >=
'0' && str[4] <=
'9') && str_len == 6) {
7897 n =
n * 16 + (str[4] -
'0');
7898 }
else if ((str[4] >=
'A' && str[4] <=
'F') && str_len == 6) {
7899 n =
n * 16 + (str[4] -
'A');
7900 }
else if ((str[4] >=
'a' && str[4] <=
'f') && str_len == 6) {
7901 n =
n * 16 + (str[4] -
'a');
7902 }
else if (str_len != 5) {
7907 }
else if (str_len == 4) {
SAPI_API sapi_module_struct sapi_module
fprintf($stream, string $format, mixed ... $values)
count(Countable|array $value, int $mode=COUNT_NORMAL)
glob(string $pattern, int $flags=0)
void zend_ffi_resolve_typedef(const char *name, size_t name_len, zend_ffi_dcl *dcl)
void zend_ffi_add_arg(HashTable **args, const char *name, size_t name_len, zend_ffi_dcl *arg_dcl)
void zend_ffi_expr_cast(zend_ffi_val *val, zend_ffi_dcl *dcl)
bool zend_ffi_is_typedef_name(const char *name, size_t name_len)
void zend_ffi_expr_plus(zend_ffi_val *val)
void zend_ffi_expr_sizeof_val(zend_ffi_val *val)
#define zend_ffi_expr_cmp(val, op2, OP)
void zend_ffi_cleanup_dcl(zend_ffi_dcl *dcl)
#define zend_ffi_expr_math(val, op2, OP)
void zend_ffi_align_as_val(zend_ffi_dcl *dcl, zend_ffi_val *align_val)
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)
zend_ffi_cdata * new_cdata
void zend_ffi_expr_alignof_val(zend_ffi_val *val)
void zend_ffi_expr_neg(zend_ffi_val *val)
void zend_ffi_expr_alignof_type(zend_ffi_val *val, zend_ffi_dcl *dcl)
struct _zend_ffi_scope zend_ffi_scope
struct _zend_ffi_symbol zend_ffi_symbol
void zend_ffi_expr_bool_or(zend_ffi_val *val, zend_ffi_val *op2)
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)
#define MAX_TYPE_NAME_LEN
#define __BIGGEST_ALIGNMENT__
void zend_ffi_adjust_struct_size(zend_ffi_dcl *dcl)
void zend_ffi_expr_div(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_bw_or(zend_ffi_val *val, zend_ffi_val *op2)
struct _zend_ffi_ctype_name_buf zend_ffi_ctype_name_buf
void zend_ffi_expr_is_less_or_equal(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_make_pointer_type(zend_ffi_dcl *dcl)
enum _zend_ffi_type_kind zend_ffi_type_kind
zend_module_entry ffi_module_entry
void zend_ffi_add_anonymous_field(zend_ffi_dcl *struct_dcl, zend_ffi_dcl *field_dcl)
void zend_ffi_expr_is_not_equal(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_expr_bw_not(zend_ffi_val *val)
void zend_ffi_declare(const char *name, size_t name_len, zend_ffi_dcl *dcl)
void zend_ffi_nested_declaration(zend_ffi_dcl *dcl, zend_ffi_dcl *nested_dcl)
void zend_ffi_expr_is_greater_or_equal(zend_ffi_val *val, zend_ffi_val *op2)
zend_ffi_cdata * old_cdata
void zend_ffi_expr_sizeof_type(zend_ffi_val *val, zend_ffi_dcl *dcl)
void zend_ffi_expr_mul(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_add_attribute_value(zend_ffi_dcl *dcl, const char *name, size_t name_len, int n, zend_ffi_val *val)
#define ZEND_FFI_VALIDATE_API_RESTRICTION()
#define SIMPLE_ATTRIBUTES(_)
memset(ptr, 0, type->size)
void zend_ffi_parser_error(const char *format,...)
#define VALUE_ATTRIBUTES(_)
struct _zend_ffi_ctype zend_ffi_ctype
void zend_ffi_expr_mod(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_shift_right(zend_ffi_val *val, zend_ffi_val *op2)
#define zend_ffi_expr_bool(val)
zend_hash_next_index_insert_new(ht, &zv)
#define ZEND_FFI_TYPE_IS_OWNED(t)
struct _zend_ffi_cdata_iterator zend_ffi_cdata_iterator
void zend_ffi_make_struct_type(zend_ffi_dcl *dcl)
struct _zend_ffi_cdata zend_ffi_cdata
void zend_ffi_expr_is_less(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_expr_bw_xor(zend_ffi_val *val, zend_ffi_val *op2)
@ ZEND_FFI_FLAG_PERSISTENT
void zend_ffi_make_func_type(zend_ffi_dcl *dcl, HashTable *args, zend_ffi_dcl *nested_dcl)
void zend_ffi_val_character(zend_ffi_val *val, const char *str, size_t str_len)
void zend_ffi_validate_type_name(zend_ffi_dcl *dcl)
void zend_ffi_expr_bw_and(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_set_abi(zend_ffi_dcl *dcl, uint16_t abi)
void zend_ffi_make_enum_type(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_val_number(zend_ffi_val *val, int base, const char *str, size_t str_len)
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_val_float_number(zend_ffi_val *val, const char *str, size_t str_len)
struct _zend_ffi zend_ffi
void zend_ffi_expr_is_greater(zend_ffi_val *val, zend_ffi_val *op2)
#define ZEND_FFI_SIZEOF_ARG
void zend_ffi_expr_bool_not(zend_ffi_val *val)
void zend_ffi_val_string(zend_ffi_val *val, const char *str, size_t str_len)
void zend_ffi_add_msvc_attribute_value(zend_ffi_dcl *dcl, const char *name, size_t name_len, zend_ffi_val *val)
enum _zend_ffi_flags zend_ffi_flags
void zend_ffi_expr_sub(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_add_attribute(zend_ffi_dcl *dcl, const char *name, size_t name_len)
struct _zend_ffi_field zend_ffi_field
zend_ffi_ctype_name_buf buf
enum _zend_ffi_tag_kind zend_ffi_tag_kind
#define ZEND_FFI_TYPE_MAKE_OWNED(t)
#define zend_ffi_expr_int_math(val, op2, OP)
void zend_ffi_make_array_type(zend_ffi_dcl *dcl, zend_ffi_val *len)
void zend_ffi_expr_conditional(zend_ffi_val *val, zend_ffi_val *op2, zend_ffi_val *op3)
enum _zend_ffi_symbol_kind zend_ffi_symbol_kind
struct _zend_ffi_tag zend_ffi_tag
void zend_ffi_expr_is_equal(zend_ffi_val *val, zend_ffi_val *op2)
void zend_ffi_align_as_type(zend_ffi_dcl *dcl, zend_ffi_dcl *align_dcl)
void zend_ffi_expr_add(zend_ffi_val *val, zend_ffi_val *op2)
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)
PHPAPI void globfree(glob_t *pglob)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
php_info_print_table_start()
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
#define ZEND_FFI_ATTR_VARIADIC
#define ZEND_FFI_ABI_THISCALL
#define ZEND_FFI_DCL_SHORT
uint32_t default_type_attr
#define ZEND_FFI_ARRAY_ATTRS
@ ZEND_FFI_VAL_LONG_DOUBLE
#define ZEND_FFI_DCL_TYPE_QUALIFIERS
#define ZEND_FFI_ENUM_ATTRS
#define ZEND_FFI_DCL_STORAGE_CLASS
#define ZEND_FFI_DCL_SIGNED
#define ZEND_FFI_DCL_TYPEDEF_NAME
#define ZEND_FFI_ATTR_UNION
#define ZEND_FFI_ABI_SYSV
#define ZEND_FFI_DCL_LONG_LONG
#define ZEND_FFI_ATTR_INCOMPLETE_ARRAY
#define ZEND_FFI_DCL_UNSIGNED
#define ZEND_FFI_ATTR_INCOMPLETE_TAG
#define ZEND_FFI_ATTR_INIT
#define ZEND_FFI_FUNC_ATTRS
#define ZEND_FFI_DCL_VOID
#define ZEND_FFI_DCL_BOOL
#define ZEND_FFI_DCL_DOUBLE
#define ZEND_FFI_DCL_TYPE_SPECIFIERS
struct _zend_ffi_val zend_ffi_val
#define ZEND_FFI_DCL_CHAR
#define ZEND_FFI_DCL_LONG
#define ZEND_FFI_ABI_VECTORCALL
#define ZEND_FFI_ABI_CDECL
#define ZEND_FFI_STRUCT_ATTRS
#define ZEND_FFI_ATTR_PERSISTENT
unsigned const char * pos
#define ZEND_FFI_ATTR_CONST
#define ZEND_FFI_ATTR_GCC_STRUCT
#define ZEND_FFI_ATTR_VLA
struct _zend_ffi_type zend_ffi_type
#define ZEND_FFI_ABI_REGISTER
struct _zend_ffi_dcl zend_ffi_dcl
#define ZEND_FFI_DCL_UNION
#define ZEND_FFI_ATTR_MS_STRUCT
#define ZEND_FFI_ABI_PASCAL
#define ZEND_FFI_POINTER_ATTRS
#define ZEND_FFI_DCL_ENUM
#define ZEND_FFI_ABI_STDCALL
#define ZEND_FFI_DCL_FLOAT
#define ZEND_FFI_ATTR_STORED
#define ZEND_FFI_DCL_STRUCT
#define ZEND_FFI_ATTR_PACKED
#define ZEND_FFI_ABI_DEFAULT
#define ZEND_FFI_DCL_COMPLEX
#define ZEND_FFI_DCL_TYPEDEF
zend_ffi_api_restriction restriction
enum _zend_ffi_api_restriction zend_ffi_api_restriction
#define ZEND_FFI_DCL_EXTERN
#define ZEND_FFI_ABI_FASTCALL
unsigned char key[REFLECTION_KEY_LEN]
#define zend_hash_str_add(...)
const zend_object_handlers * default_object_handlers
zend_function * function_handler
char buf[MAX_TYPE_NAME_LEN]
zend_ffi_symbol_kind kind
struct _zend_ffi_type::@016056046110312112304362000360146030316332334371::@264332254304206364037301264275004040070170034140 enumeration
struct _zend_ffi_type::@016056046110312112304362000360146030316332334371::@016273327024364333303163264267270207017133345054 record
struct _zend_ffi_type::@016056046110312112304362000360146030316332334371::@053310066131114376053345112132043236062316034044 func
struct _zend_ffi_type::@016056046110312112304362000360146030316332334371::@052202136307211065107064172217256343171104062000 array
struct _zend_ffi_type::@016056046110312112304362000360146030316332334371::@260375113037176215306035042226230373011016312351 pointer
const zend_object_iterator_funcs * funcs
struct _zend_function::@236135173067030250234125302313220025134003177336 common
PHP_WINUTIL_API void php_win32_error_msg_free(char *msg)
ZEND_API zend_string * zend_strpprintf(size_t max_len, const char *format,...)
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
ZEND_API zend_result(* zend_post_startup_cb)(void)
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap)
#define ZEND_TSRMLS_CACHE_UPDATE()
#define ZEND_TSRMLS_CACHE_DEFINE()
ZEND_API const char * zend_zval_value_name(const zval *arg)
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg)
ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error)
struct _zend_fcall_info_cache zend_fcall_info_cache
#define Z_PARAM_OBJ_OF_CLASS_OR_STR(destination_object, base_ce, destination_string)
#define RETURN_STRINGL(s, l)
#define ZEND_PARSE_PARAMETERS_END()
#define Z_PARAM_STR_OR_NULL(dest)
#define ZEND_MINIT_FUNCTION
#define ZEND_GSHUTDOWN_FUNCTION
#define ZVAL_STRING(z, s)
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
#define ZEND_GET_MODULE(name)
#define zend_parse_parameters_none()
#define Z_PARAM_STR(dest)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define Z_PARAM_LONG(dest)
#define Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, check_null, deref)
#define ZEND_GSHUTDOWN(module)
#define ZEND_RSHUTDOWN_FUNCTION
#define ZEND_MINFO_FUNCTION
struct _zend_fcall_info zend_fcall_info
#define ZEND_METHOD(classname, name)
#define Z_PARAM_ARRAY_HT(dest)
#define ZEND_GINIT(module)
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
#define Z_PARAM_BOOL(dest)
#define Z_PARAM_OBJECT_OF_CLASS(dest, _ce)
#define Z_PARAM_ZVAL(dest)
#define ZEND_GINIT_FUNCTION
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define ZEND_FUNCTION(name)
#define RETURN_STR_COPY(s)
#define estrndup(s, length)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define pemalloc(size, persistent)
#define erealloc(ptr, size)
strncmp(string $string1, string $string2, int $length)
exit(string|int $status=0)
strcmp(string $string1, string $string2)
#define ZEND_CLOSURE_OBJECT(op_array)
#define ZEND_COMPILE_PRELOAD
#define ZEND_INTERNAL_FUNCTION
#define ZEND_ACC_CALL_VIA_TRAMPOLINE
#define ZEND_ACC_PRELOADED
struct _zend_internal_function zend_internal_function
#define ZEND_COMPILE_PRELOAD_IN_CHILD
ZEND_API ZEND_COLD zend_object * zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code)
ZEND_API zend_class_entry * zend_ce_error
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
union _zend_function zend_function
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
ZEND_API const HashTable zend_empty_array
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val)
#define ZEND_HASH_PACKED_FOREACH_KEY_PTR(ht, _h, _ptr)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_PACKED_FOREACH_PTR(ht, _ptr)
#define zend_new_array(size)
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
#define ZEND_HASH_PACKED_FOREACH_VAL(ht, _val)
#define ZEND_HASH_MAP_REVERSE_FOREACH_PTR(ht, _ptr)
ZEND_API bool zend_ini_parse_bool(zend_string *str)
#define ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, displayer)
#define REGISTER_INI_ENTRIES()
#define DISPLAY_INI_ENTRIES()
#define ZEND_INI_MH(name)
#define ZEND_INI_DISP(name)
#define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr)
ZEND_API void zend_iterator_init(zend_object_iterator *iter)
struct _zend_object_iterator zend_object_iterator
struct _zend_object_iterator_funcs zend_object_iterator_funcs
#define MAX_LENGTH_OF_LONG
struct _zend_string zend_string
#define ZEND_MAP_PTR(ptr)
#define STANDARD_MODULE_HEADER
#define ZEND_MODULE_GLOBALS(module_name)
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES_EX
#define zend_free_trampoline(func)
#define zend_get_std_object_handlers()
ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
#define ZEND_OBSERVER_ENABLED
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
#define ZEND_UNCOMPARABLE
#define convert_to_string(op)
#define ALLOCA_FLAG(name)
#define zend_never_inline
#define ZEND_ELEMENT_COUNT(m)
#define EXPECTED(condition)
#define do_alloca(p, use_heap)
#define zend_always_inline
#define ZEND_UNREACHABLE()
#define free_alloca(p, use_heap)
#define ZEND_PATHS_SEPARATOR
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
ZEND_API zend_string * zend_string_concat3(const char *str1, size_t str1_len, const char *str2, size_t str2_len, const char *str3, size_t str3_len)
#define zend_string_equals_literal(str, literal)
#define zend_string_equals_literal_ci(str, c)
#define GC_SET_REFCOUNT(p, rc)
#define Z_STRVAL_P(zval_p)
#define ZVAL_STR_COPY(z, s)
struct _zend_array HashTable
#define IS_OBJ_DESTRUCTOR_CALLED
#define Z_STRLEN_P(zval_p)
#define Z_OBJCE_P(zval_p)
#define ZVAL_DOUBLE(z, d)
ZEND_RESULT_CODE zend_result
#define IS_OBJ_WEAKLY_REFERENCED
struct _zend_object_handlers zend_object_handlers
struct _zend_execute_data zend_execute_data
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
void zend_weakrefs_notify(zend_object *object)