From c5259a44739bf64ee2670ebb84f552406b7b62ac Mon Sep 17 00:00:00 2001 From: chopins Date: Mon, 16 May 2022 14:42:37 +0800 Subject: [PATCH 01/14] update --- ext/ffi/ffi.c | 60 ++++++++++++++++++++++++++++++++++++++------ ext/ffi/ffi.stub.php | 3 +++ 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 44cce8227ea68..70c5e29673be6 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -190,10 +190,12 @@ typedef struct _zend_ffi_ctype { static zend_class_entry *zend_ffi_exception_ce; static zend_class_entry *zend_ffi_parser_exception_ce; static zend_class_entry *zend_ffi_ce; +static zend_class_entry *zend_ffi_cdef_ce; static zend_class_entry *zend_ffi_cdata_ce; static zend_class_entry *zend_ffi_ctype_ce; static zend_object_handlers zend_ffi_handlers; +static zend_object_handlers zend_ffi_cdef_handlers; static zend_object_handlers zend_ffi_cdata_handlers; static zend_object_handlers zend_ffi_cdata_value_handlers; static zend_object_handlers zend_ffi_cdata_free_handlers; @@ -2199,6 +2201,23 @@ static HashTable *zend_ffi_ctype_get_debug_info(zend_object *obj, int *is_temp) } /* }}} */ +static zend_object *zend_ffi_cdef_new(zend_class_entry *class_type) /* {{{ */ +{ + zend_ffi *ffi; + + ffi = emalloc(sizeof(zend_ffi)); + + zend_ffi_object_init(&ffi->std, class_type); + ffi->std.handlers = &zend_ffi_cdef_handlers; + + ffi->lib = NULL; + ffi->symbols = NULL; + ffi->tags = NULL; + ffi->persistent = 0; + + return &ffi->std; +} + static zend_object *zend_ffi_new(zend_class_entry *class_type) /* {{{ */ { zend_ffi *ffi; @@ -2786,7 +2805,7 @@ static zend_function *zend_ffi_get_func(zend_object **obj, zend_string *name, co zend_ffi_symbol *sym = NULL; zend_function *func; zend_ffi_type *type; - + /* if (ZSTR_LEN(name) == sizeof("new") -1 && (ZSTR_VAL(name)[0] == 'n' || ZSTR_VAL(name)[0] == 'N') && (ZSTR_VAL(name)[1] == 'e' || ZSTR_VAL(name)[1] == 'E') @@ -2805,7 +2824,7 @@ static zend_function *zend_ffi_get_func(zend_object **obj, zend_string *name, co && (ZSTR_VAL(name)[3] == 'e' || ZSTR_VAL(name)[3] == 'E')) { return (zend_function*)&zend_ffi_type_fn; } - + */ if (ffi->symbols) { sym = zend_hash_find_ptr(ffi->symbols, name); if (sym && sym->kind != ZEND_FFI_SYM_FUNC) { @@ -2953,7 +2972,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ } } - ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce); + ffi = (zend_ffi*)zend_ffi_cdef_new(zend_ffi_cdef_ce); ffi->lib = handle; ffi->symbols = FFI_G(symbols); ffi->tags = FFI_G(tags); @@ -3374,7 +3393,7 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */ } if (EG(objects_store).object_buckets) { - ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce); + ffi = (zend_ffi*)zend_ffi_cdef_new(zend_ffi_cdef_ce); } else { ffi = ecalloc(1, sizeof(zend_ffi)); } @@ -3382,7 +3401,7 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */ ffi->tags = scope->tags; ffi->persistent = 1; } else { - ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce); + ffi = (zend_ffi*)zend_ffi_cdef_new(zend_ffi_cdef_ce); ffi->lib = handle; ffi->symbols = FFI_G(symbols); ffi->tags = FFI_G(tags); @@ -3455,7 +3474,7 @@ ZEND_METHOD(FFI, scope) /* {{{ */ RETURN_THROWS(); } - ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce); + ffi = (zend_ffi*)zend_ffi_cdef_new(zend_ffi_cdef_ce); ffi->symbols = scope->symbols; ffi->tags = scope->tags; @@ -5253,13 +5272,14 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_ce = register_class_FFI(); zend_ffi_ce->create_object = zend_ffi_new; - + /* memcpy(&zend_ffi_new_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "new", sizeof("new")-1), sizeof(zend_internal_function)); zend_ffi_new_fn.fn_flags &= ~ZEND_ACC_STATIC; memcpy(&zend_ffi_cast_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "cast", sizeof("cast")-1), sizeof(zend_internal_function)); zend_ffi_cast_fn.fn_flags &= ~ZEND_ACC_STATIC; memcpy(&zend_ffi_type_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "type", sizeof("type")-1), sizeof(zend_internal_function)); zend_ffi_type_fn.fn_flags &= ~ZEND_ACC_STATIC; + */ memcpy(&zend_ffi_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); zend_ffi_handlers.get_constructor = zend_fake_get_constructor; @@ -5274,7 +5294,7 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_handlers.unset_property = zend_fake_unset_property; zend_ffi_handlers.has_dimension = zend_fake_has_dimension; zend_ffi_handlers.unset_dimension = zend_fake_unset_dimension; - zend_ffi_handlers.get_method = zend_ffi_get_func; + zend_ffi_handlers.get_method = zend_fake_get_method; zend_ffi_handlers.compare = NULL; zend_ffi_handlers.cast_object = zend_fake_cast_object; zend_ffi_handlers.get_debug_info = NULL; @@ -5284,6 +5304,30 @@ ZEND_MINIT_FUNCTION(ffi) zend_declare_class_constant_long(zend_ffi_ce, "__BIGGEST_ALIGNMENT__", sizeof("__BIGGEST_ALIGNMENT__")-1, __BIGGEST_ALIGNMENT__); + zend_ffi_cdef_ce = register_class_FFI_CDef(); + zend_ffi_cdef_cdef_ce->create_object = zend_ffi_cdef_new; + + memcpy(%zend_ffi_cdef_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_ffi_def_handlers.get_constructor = zend_fake_get_constructor; + zend_ffi_def_handlers.free_obj = zend_ffi_cdef_free_obj; + zend_ffi_def_handlers.clone_obj = NULL; + zend_ffi_def_handlers.read_property = zend_ffi_cdef_read_var; + zend_ffi_def_handlers.write_property = zend_ffi_cdef_write_var; + zend_ffi_def_handlers.read_dimension = zend_fake_read_dimension; + zend_ffi_def_handlers.write_dimension = zend_fake_write_dimension; + zend_ffi_def_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; + zend_ffi_def_handlers.has_property = zend_fake_has_property; + zend_ffi_def_handlers.unset_property = zend_fake_unset_property; + zend_ffi_def_handlers.has_dimension = zend_fake_has_dimension; + zend_ffi_def_handlers.unset_dimension = zend_fake_unset_dimension; + zend_ffi_def_handlers.get_method = zend_ffi_get_func; + zend_ffi_def_handlers.compare = NULL; + zend_ffi_def_handlers.cast_object = zend_fake_cast_object; + zend_ffi_def_handlers.get_debug_info = NULL; + zend_ffi_def_handlers.get_closure = NULL; + zend_ffi_def_handlers.get_properties = zend_fake_get_properties; + zend_ffi_def_handlers.get_gc = zend_fake_get_gc; + zend_ffi_cdata_ce = register_class_FFI_CData(); zend_ffi_cdata_ce->create_object = zend_ffi_cdata_new; zend_ffi_cdata_ce->get_iterator = zend_ffi_cdata_get_iterator; diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php index 6ba7b542ef97d..d8b8b738c61a2 100644 --- a/ext/ffi/ffi.stub.php +++ b/ext/ffi/ffi.stub.php @@ -68,6 +68,9 @@ public static function isNull(FFI\CData $ptr): bool {} } namespace FFI { + /** @not-serializable */ + final class CDef { + } /** @not-serializable */ final class CData { From 87f7f8ceba85e8418126a6c40eefa3af2652c0d4 Mon Sep 17 00:00:00 2001 From: chopins Date: Mon, 16 May 2022 15:00:48 +0800 Subject: [PATCH 02/14] update --- ext/ffi/ffi.c | 66 ++++++++++++++++++++++++++++++++------------ ext/ffi/ffi.stub.php | 6 ++-- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 70c5e29673be6..2958d0451c65a 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -2355,6 +2355,30 @@ static void zend_ffi_scope_hash_dtor(zval *zv) /* {{{ */ } /* }}} */ +static void zend_ffi_cdef_free_obj(zend_object *object) /* {{{ */ +{ + zend_ffi *ffi = (zend_ffi*)object; + + if (ffi->persistent) { + return; + } + + if (ffi->lib) { + DL_UNLOAD(ffi->lib); + ffi->lib = NULL; + } + + if (ffi->symbols) { + zend_hash_destroy(ffi->symbols); + efree(ffi->symbols); + } + + if (ffi->tags) { + zend_hash_destroy(ffi->tags); + efree(ffi->tags); + } +} + static void zend_ffi_free_obj(zend_object *object) /* {{{ */ { zend_ffi *ffi = (zend_ffi*)object; @@ -2407,7 +2431,7 @@ static zend_object *zend_ffi_cdata_clone_obj(zend_object *obj) /* {{{ */ } /* }}} */ -static zval *zend_ffi_read_var(zend_object *obj, zend_string *var_name, int read_type, void **cache_slot, zval *rv) /* {{{ */ +static zval *zend_ffi_cdef_read_var(zend_object *obj, zend_string *var_name, int read_type, void **cache_slot, zval *rv) /* {{{ */ { zend_ffi *ffi = (zend_ffi*)obj; zend_ffi_symbol *sym = NULL; @@ -2451,7 +2475,7 @@ static zval *zend_ffi_read_var(zend_object *obj, zend_string *var_name, int read } /* }}} */ -static zval *zend_ffi_write_var(zend_object *obj, zend_string *var_name, zval *value, void **cache_slot) /* {{{ */ +static zval *zend_ffi_cdef_write_var(zend_object *obj, zend_string *var_name, zval *value, void **cache_slot) /* {{{ */ { zend_ffi *ffi = (zend_ffi*)obj; zend_ffi_symbol *sym = NULL; @@ -3659,6 +3683,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ zend_object *type_obj = NULL; zend_ffi_type *type, *type_ptr; zend_ffi_cdata *cdata; + zend_ffi_cdef_handlers *cdef; void *ptr; bool owned = 1; bool persistent = 0; @@ -3666,11 +3691,12 @@ ZEND_METHOD(FFI, new) /* {{{ */ zend_ffi_flags flags = ZEND_FFI_FLAG_OWNED; ZEND_FFI_VALIDATE_API_RESTRICTION(); - ZEND_PARSE_PARAMETERS_START(1, 3) + ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_OBJ_OF_CLASS_OR_STR(type_obj, zend_ffi_ctype_ce, type_def) Z_PARAM_OPTIONAL Z_PARAM_BOOL(owned) Z_PARAM_BOOL(persistent) + Z_PARAM_OBJ_OR_NULL(cdef) ZEND_PARSE_PARAMETERS_END(); if (!owned) { @@ -3684,8 +3710,8 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (type_def) { zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; - if (Z_TYPE(EX(This)) == IS_OBJECT) { - zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This)); + if (Z_TYPE(EX(cdef)) == IS_OBJECT) { + zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(cdef)); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; } else { @@ -3697,7 +3723,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE(EX(This)) != IS_OBJECT) { + if (Z_TYPE(EX(cdef)) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3812,14 +3838,17 @@ ZEND_METHOD(FFI, cast) /* {{{ */ zend_object *ztype = NULL; zend_ffi_type *old_type, *type, *type_ptr; zend_ffi_cdata *old_cdata, *cdata; + zend_ffi_cdef_handlers *cdef; bool is_const = 0; zval *zv, *arg; void *ptr; ZEND_FFI_VALIDATE_API_RESTRICTION(); - ZEND_PARSE_PARAMETERS_START(2, 2) + ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_OBJ_OF_CLASS_OR_STR(ztype, zend_ffi_ctype_ce, type_def) Z_PARAM_ZVAL(zv) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OR_NULL(cdef) ZEND_PARSE_PARAMETERS_END(); arg = zv; @@ -3828,8 +3857,8 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (type_def) { zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; - if (Z_TYPE(EX(This)) == IS_OBJECT) { - zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This)); + if (Z_TYPE(EX(cdef)) == IS_OBJECT) { + zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(cdef)); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; } else { @@ -3841,7 +3870,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE(EX(This)) != IS_OBJECT) { + if (Z_TYPE(EX(cdef)) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3988,14 +4017,17 @@ ZEND_METHOD(FFI, type) /* {{{ */ zend_ffi_ctype *ctype; zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; zend_string *type_def; + zend_ffi_cdef_handlers *cdef; ZEND_FFI_VALIDATE_API_RESTRICTION(); - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(type_def); + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OR_NULL(cdef) ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE(EX(This)) == IS_OBJECT) { - zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This)); + if (Z_TYPE(EX(cdef)) == IS_OBJECT) { + zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(cdef)); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; } else { @@ -4007,7 +4039,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE(EX(This)) != IS_OBJECT) { + if (Z_TYPE(EX(cdef)) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -4022,7 +4054,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ return; } - if (Z_TYPE(EX(This)) != IS_OBJECT) { + if (Z_TYPE(EX(cdef)) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -5285,8 +5317,8 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_handlers.get_constructor = zend_fake_get_constructor; zend_ffi_handlers.free_obj = zend_ffi_free_obj; zend_ffi_handlers.clone_obj = NULL; - zend_ffi_handlers.read_property = zend_ffi_read_var; - zend_ffi_handlers.write_property = zend_ffi_write_var; + zend_ffi_handlers.read_property = zend_fake_read_property; + zend_ffi_handlers.write_property = zend_fake_write_var; zend_ffi_handlers.read_dimension = zend_fake_read_dimension; zend_ffi_handlers.write_dimension = zend_fake_write_dimension; zend_ffi_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php index d8b8b738c61a2..260f19494f120 100644 --- a/ext/ffi/ffi.stub.php +++ b/ext/ffi/ffi.stub.php @@ -13,7 +13,7 @@ public static function load(string $filename): ?FFI {} public static function scope(string $name): FFI {} - public static function new(FFI\CType|string $type, bool $owned = true, bool $persistent = false): ?FFI\CData {} + public static function new(FFI\CType|string $type, bool $owned = true, bool $persistent = false, ?FFI\CDef $cdef = null): ?FFI\CData {} /** @prefer-ref $ptr */ public static function free(FFI\CData $ptr): void {} @@ -22,9 +22,9 @@ public static function free(FFI\CData $ptr): void {} * @param FFI\CData|int|float|bool|null $ptr * @prefer-ref $ptr */ - public static function cast(FFI\CType|string $type, $ptr): ?FFI\CData {} + public static function cast(FFI\CType|string $type, $ptr, ?FFI\CDef $cdef = null): ?FFI\CData {} - public static function type(string $type): ?FFI\CType {} + public static function type(string $type, ?FFI\CDef $cdef = null): ?FFI\CType {} /** @prefer-ref $ptr */ public static function typeof(FFI\CData $ptr): FFI\CType {} From 3e064dfb4128decaeaec4e90363f6578fa37a1b3 Mon Sep 17 00:00:00 2001 From: chopins Date: Mon, 16 May 2022 15:15:20 +0800 Subject: [PATCH 03/14] update --- ext/ffi/ffi.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 2958d0451c65a..675ca1aa62499 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -2220,19 +2220,12 @@ static zend_object *zend_ffi_cdef_new(zend_class_entry *class_type) /* {{{ */ static zend_object *zend_ffi_new(zend_class_entry *class_type) /* {{{ */ { - zend_ffi *ffi; - - ffi = emalloc(sizeof(zend_ffi)); - - zend_ffi_object_init(&ffi->std, class_type); - ffi->std.handlers = &zend_ffi_handlers; + zend_object *ffi_obj; - ffi->lib = NULL; - ffi->symbols = NULL; - ffi->tags = NULL; - ffi->persistent = 0; + zend_ffi_object_init(ffi_obj, class_type); + ffi_obj->handlers = &zend_ffi_handlers; - return &ffi->std; + return &ffi_obj; } /* }}} */ From f4e5686ee0448542d4be6bbca834d0ae33313f5e Mon Sep 17 00:00:00 2001 From: chopins Date: Mon, 16 May 2022 15:33:12 +0800 Subject: [PATCH 04/14] updatE --- ext/ffi/ffi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 675ca1aa62499..0efcc282267ff 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -3689,7 +3689,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ Z_PARAM_OPTIONAL Z_PARAM_BOOL(owned) Z_PARAM_BOOL(persistent) - Z_PARAM_OBJ_OR_NULL(cdef) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(cdef, zend_ffi_cdef_ce) ZEND_PARSE_PARAMETERS_END(); if (!owned) { @@ -3841,7 +3841,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ Z_PARAM_OBJ_OF_CLASS_OR_STR(ztype, zend_ffi_ctype_ce, type_def) Z_PARAM_ZVAL(zv) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OR_NULL(cdef) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(cdef, zend_ffi_cdef_ce) ZEND_PARSE_PARAMETERS_END(); arg = zv; @@ -4016,7 +4016,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(type_def); Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OR_NULL(cdef) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(cdef, zend_ffi_cdef_ce) ZEND_PARSE_PARAMETERS_END(); if (Z_TYPE(EX(cdef)) == IS_OBJECT) { From 56ac3e2f310d8e0b8eedb3a001baec23abf75715 Mon Sep 17 00:00:00 2001 From: chopins Date: Mon, 16 May 2022 15:44:06 +0800 Subject: [PATCH 05/14] updatE --- ext/ffi/ffi.c | 4 ++++ ext/ffi/ffi.stub.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 0efcc282267ff..2a3e4fbd42836 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -5328,6 +5328,10 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_handlers.get_gc = zend_fake_get_gc; zend_declare_class_constant_long(zend_ffi_ce, "__BIGGEST_ALIGNMENT__", sizeof("__BIGGEST_ALIGNMENT__")-1, __BIGGEST_ALIGNMENT__); + zend_declare_class_constant_long(zend_ffi_ce, "SYM_TYPE", sizeof("SYM_TYPE")-1, ZEND_FFI_SYM_TYPE); + zend_declare_class_constant_long(zend_ffi_ce, "SYM_CONST", sizeof("SYM_CONST")-1, ZEND_FFI_SYM_CONST); + zend_declare_class_constant_long(zend_ffi_ce, "SYM_VAR", sizeof("SYM_VAR")-1, ZEND_FFI_SYM_VAR); + zend_declare_class_constant_long(zend_ffi_ce, "SYM_FUNC", sizeof("SYM_FUNC")-1, ZEND_FFI_SYM_FUNC); zend_ffi_cdef_ce = register_class_FFI_CDef(); zend_ffi_cdef_cdef_ce->create_object = zend_ffi_cdef_new; diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php index 260f19494f120..6ba1b2c3779db 100644 --- a/ext/ffi/ffi.stub.php +++ b/ext/ffi/ffi.stub.php @@ -63,6 +63,10 @@ public static function string(FFI\CData $ptr, ?int $size = null): string {} /** @prefer-ref $ptr */ public static function isNull(FFI\CData $ptr): bool {} + + public static function hasSymbol(FFI\CDef $cdef, $symbol, $type): bool {} + + public static function getSymbols(FFI\CDef $cdef, $type): array {} } } From 1d12aa9611695b853d8eefcab8cf3fa7cdde4b72 Mon Sep 17 00:00:00 2001 From: chopins Date: Mon, 16 May 2022 16:31:25 +0800 Subject: [PATCH 06/14] update --- ext/ffi/ffi.c | 100 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 40 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 2a3e4fbd42836..7dc8d4ba1b85d 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -201,10 +201,11 @@ static zend_object_handlers zend_ffi_cdata_value_handlers; static zend_object_handlers zend_ffi_cdata_free_handlers; static zend_object_handlers zend_ffi_ctype_handlers; +/* static zend_internal_function zend_ffi_new_fn; static zend_internal_function zend_ffi_cast_fn; static zend_internal_function zend_ffi_type_fn; - +*/ /* forward declarations */ static void _zend_ffi_type_dtor(zend_ffi_type *type); static void zend_ffi_finalize_type(zend_ffi_dcl *dcl); @@ -2225,7 +2226,7 @@ static zend_object *zend_ffi_new(zend_class_entry *class_type) /* {{{ */ zend_ffi_object_init(ffi_obj, class_type); ffi_obj->handlers = &zend_ffi_handlers; - return &ffi_obj; + return ffi_obj; } /* }}} */ @@ -3676,7 +3677,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ zend_object *type_obj = NULL; zend_ffi_type *type, *type_ptr; zend_ffi_cdata *cdata; - zend_ffi_cdef_handlers *cdef; + zval *cdef; void *ptr; bool owned = 1; bool persistent = 0; @@ -3703,8 +3704,8 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (type_def) { zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; - if (Z_TYPE(EX(cdef)) == IS_OBJECT) { - zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(cdef)); + if (Z_TYPE_P(cdef) == IS_OBJECT) { + zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; } else { @@ -3716,7 +3717,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE(EX(cdef)) != IS_OBJECT) { + if (Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3736,7 +3737,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ is_const = 1; } - if (Z_TYPE(EX(This)) != IS_OBJECT) { + if (Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -3831,7 +3832,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ zend_object *ztype = NULL; zend_ffi_type *old_type, *type, *type_ptr; zend_ffi_cdata *old_cdata, *cdata; - zend_ffi_cdef_handlers *cdef; + zval *cdef; bool is_const = 0; zval *zv, *arg; void *ptr; @@ -3850,8 +3851,8 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (type_def) { zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; - if (Z_TYPE(EX(cdef)) == IS_OBJECT) { - zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(cdef)); + if (Z_TYPE_P(cdef) == IS_OBJECT) { + zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; } else { @@ -3863,7 +3864,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE(EX(cdef)) != IS_OBJECT) { + if (Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3883,7 +3884,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ is_const = 1; } - if (Z_TYPE(EX(This)) != IS_OBJECT) { + if (Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -4010,7 +4011,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ zend_ffi_ctype *ctype; zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; zend_string *type_def; - zend_ffi_cdef_handlers *cdef; + zval *cdef; ZEND_FFI_VALIDATE_API_RESTRICTION(); ZEND_PARSE_PARAMETERS_START(1, 2) @@ -4019,8 +4020,8 @@ ZEND_METHOD(FFI, type) /* {{{ */ Z_PARAM_OBJECT_OF_CLASS_OR_NULL(cdef, zend_ffi_cdef_ce) ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE(EX(cdef)) == IS_OBJECT) { - zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(cdef)); + if (Z_TYPE_P(cdef) == IS_OBJECT) { + zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; } else { @@ -4032,7 +4033,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE(EX(cdef)) != IS_OBJECT) { + if (Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -4047,7 +4048,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ return; } - if (Z_TYPE(EX(cdef)) != IS_OBJECT) { + if (Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -4523,6 +4524,25 @@ ZEND_METHOD(FFI, isNull) /* {{{ */ } /* }}} */ +ZEND_METHOD(FFI, hasSymbol) /* {{{ */ +{ + zval *cdef; + ZEND_FFI_VALIDATE_API_RESTRICTION(); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(cdef, zend_ffi_cdef_ce) + ZEND_PARSE_PARAMETERS_END(); +} +/* }}} */ + +ZEND_METHOD(FFI, getSymbols) /* {{{ */ +{ + zval *cdef; + ZEND_FFI_VALIDATE_API_RESTRICTION(); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS(cdef, zend_ffi_cdef_ce) + ZEND_PARSE_PARAMETERS_END(); +} +/* }}} */ ZEND_METHOD(FFI_CType, getName) /* {{{ */ { @@ -5311,7 +5331,7 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_handlers.free_obj = zend_ffi_free_obj; zend_ffi_handlers.clone_obj = NULL; zend_ffi_handlers.read_property = zend_fake_read_property; - zend_ffi_handlers.write_property = zend_fake_write_var; + zend_ffi_handlers.write_property = zend_fake_write_property; zend_ffi_handlers.read_dimension = zend_fake_read_dimension; zend_ffi_handlers.write_dimension = zend_fake_write_dimension; zend_ffi_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; @@ -5334,28 +5354,28 @@ ZEND_MINIT_FUNCTION(ffi) zend_declare_class_constant_long(zend_ffi_ce, "SYM_FUNC", sizeof("SYM_FUNC")-1, ZEND_FFI_SYM_FUNC); zend_ffi_cdef_ce = register_class_FFI_CDef(); - zend_ffi_cdef_cdef_ce->create_object = zend_ffi_cdef_new; - - memcpy(%zend_ffi_cdef_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - zend_ffi_def_handlers.get_constructor = zend_fake_get_constructor; - zend_ffi_def_handlers.free_obj = zend_ffi_cdef_free_obj; - zend_ffi_def_handlers.clone_obj = NULL; - zend_ffi_def_handlers.read_property = zend_ffi_cdef_read_var; - zend_ffi_def_handlers.write_property = zend_ffi_cdef_write_var; - zend_ffi_def_handlers.read_dimension = zend_fake_read_dimension; - zend_ffi_def_handlers.write_dimension = zend_fake_write_dimension; - zend_ffi_def_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; - zend_ffi_def_handlers.has_property = zend_fake_has_property; - zend_ffi_def_handlers.unset_property = zend_fake_unset_property; - zend_ffi_def_handlers.has_dimension = zend_fake_has_dimension; - zend_ffi_def_handlers.unset_dimension = zend_fake_unset_dimension; - zend_ffi_def_handlers.get_method = zend_ffi_get_func; - zend_ffi_def_handlers.compare = NULL; - zend_ffi_def_handlers.cast_object = zend_fake_cast_object; - zend_ffi_def_handlers.get_debug_info = NULL; - zend_ffi_def_handlers.get_closure = NULL; - zend_ffi_def_handlers.get_properties = zend_fake_get_properties; - zend_ffi_def_handlers.get_gc = zend_fake_get_gc; + zend_ffi_cdef_ce->create_object = zend_ffi_cdef_new; + + memcpy(&zend_ffi_cdef_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_ffi_cdef_handlers.get_constructor = zend_fake_get_constructor; + zend_ffi_cdef_handlers.free_obj = zend_ffi_cdef_free_obj; + zend_ffi_cdef_handlers.clone_obj = NULL; + zend_ffi_cdef_handlers.read_property = zend_ffi_cdef_read_var; + zend_ffi_cdef_handlers.write_property = zend_ffi_cdef_write_var; + zend_ffi_cdef_handlers.read_dimension = zend_fake_read_dimension; + zend_ffi_cdef_handlers.write_dimension = zend_fake_write_dimension; + zend_ffi_cdef_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; + zend_ffi_cdef_handlers.has_property = zend_fake_has_property; + zend_ffi_cdef_handlers.unset_property = zend_fake_unset_property; + zend_ffi_cdef_handlers.has_dimension = zend_fake_has_dimension; + zend_ffi_cdef_handlers.unset_dimension = zend_fake_unset_dimension; + zend_ffi_cdef_handlers.get_method = zend_ffi_get_func; + zend_ffi_cdef_handlers.compare = NULL; + zend_ffi_cdef_handlers.cast_object = zend_fake_cast_object; + zend_ffi_cdef_handlers.get_debug_info = NULL; + zend_ffi_cdef_handlers.get_closure = NULL; + zend_ffi_cdef_handlers.get_properties = zend_fake_get_properties; + zend_ffi_cdef_handlers.get_gc = zend_fake_get_gc; zend_ffi_cdata_ce = register_class_FFI_CData(); zend_ffi_cdata_ce->create_object = zend_ffi_cdata_new; From ea37a337cd07f31ed10922260d8456d37aad31b7 Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 15:17:47 +0800 Subject: [PATCH 07/14] update --- ext/ffi/ffi.c | 71 +++++++++++++++++++++++++++++++------ ext/ffi/ffi.stub.php | 10 +++--- ext/ffi/ffi_arginfo.h | 42 +++++++++++++++++++--- ext/ffi/tests/003.phpt | 12 +++---- ext/ffi/tests/004.phpt | 18 +++++----- ext/ffi/tests/020.phpt | 2 +- ext/ffi/tests/029.phpt | 4 +-- ext/ffi/tests/044.phpt | 20 +++++------ ext/ffi/tests/100.phpt | 2 +- ext/ffi/tests/101.phpt | 2 +- ext/ffi/tests/bug77768.phpt | 2 +- ext/ffi/tests/bug78543.phpt | 2 +- ext/ffi/tests/bug79571.phpt | 2 +- ext/ffi/tests/bug80847.phpt | 2 +- ext/ffi/tests/gh8433.phpt | 4 +-- ext/ffi/tests/list.phpt | 4 +-- 16 files changed, 142 insertions(+), 57 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 7dc8d4ba1b85d..2cafbc124c030 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -3851,7 +3851,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (type_def) { zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; - if (Z_TYPE_P(cdef) == IS_OBJECT) { + if (cdef && Z_TYPE_P(cdef) == IS_OBJECT) { zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; @@ -3864,7 +3864,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3884,7 +3884,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ is_const = 1; } - if (Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -4020,7 +4020,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ Z_PARAM_OBJECT_OF_CLASS_OR_NULL(cdef, zend_ffi_cdef_ce) ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(cdef) == IS_OBJECT) { + if (cdef && Z_TYPE_P(cdef) == IS_OBJECT) { zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; @@ -4033,7 +4033,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -4048,7 +4048,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ return; } - if (Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -4527,20 +4527,71 @@ ZEND_METHOD(FFI, isNull) /* {{{ */ ZEND_METHOD(FFI, hasSymbol) /* {{{ */ { zval *cdef; + zend_string *symbol; + zend_long symbol_kind; + bool kind_is_null = 1; + zend_ffi_symbol *sym = NULL; + ZEND_FFI_VALIDATE_API_RESTRICTION(); - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJ_OF_CLASS(cdef, zend_ffi_cdef_ce) + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_OBJECT_OF_CLASS(cdef, zend_ffi_cdef_ce) + Z_PARAM_STR(symbol) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(symbol_kind, kind_is_null) ZEND_PARSE_PARAMETERS_END(); + + if (!kind_is_null && (symbol_kind > ZEND_FFI_SYM_FUNC || symbol_kind < ZEND_FFI_SYM_TYPE)) { + zend_argument_value_error(2, "must be a valid symbol kind"); + RETURN_THROWS(); + } + + zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); + sym = zend_hash_find_ptr(ffi->symbols, symbol); + if (!sym) { + RETURN_FALSE; + } + if (!kind_is_null && sym->kind != symbol_kind) { + RETURN_FALSE; + } + RETURN_TRUE; } /* }}} */ ZEND_METHOD(FFI, getSymbols) /* {{{ */ { zval *cdef; + zend_long symbol_kind; + bool kind_is_null = 1; + zval ctype_object; + ZEND_FFI_VALIDATE_API_RESTRICTION(); - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJ_OF_CLASS(cdef, zend_ffi_cdef_ce) + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(cdef, zend_ffi_cdef_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(symbol_kind, kind_is_null) ZEND_PARSE_PARAMETERS_END(); + + if (!kind_is_null && (symbol_kind > ZEND_FFI_SYM_FUNC || symbol_kind < ZEND_FFI_SYM_TYPE)) { + zend_argument_value_error(2, "must be a valid symbol kind"); + RETURN_THROWS(); + } + + zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); + zend_string *name; + zend_ffi_symbol *sym; + + array_init(return_value); + + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ffi->symbols, name, sym) { + if(!kind_is_null && symbol_kind != sym->kind) { + continue; + } + zend_ffi_ctype *ctype = (zend_ffi_ctype*)zend_ffi_ctype_new(zend_ffi_ctype_ce); + ctype->type = sym->type; + + ZVAL_OBJ_COPY(&ctype_object, &ctype->std); + zend_hash_add_new(Z_ARRVAL_P(return_value), name, &ctype_object); + } ZEND_HASH_FOREACH_END(); } /* }}} */ diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php index 6ba1b2c3779db..93744396a910e 100644 --- a/ext/ffi/ffi.stub.php +++ b/ext/ffi/ffi.stub.php @@ -7,11 +7,11 @@ /** @not-serializable */ final class FFI { - public static function cdef(string $code = "", ?string $lib = null): FFI {} + public static function cdef(string $code = "", ?string $lib = null): FFI\CDef {} - public static function load(string $filename): ?FFI {} + public static function load(string $filename): ?FFI\CDef {} - public static function scope(string $name): FFI {} + public static function scope(string $name): FFI\CDef {} public static function new(FFI\CType|string $type, bool $owned = true, bool $persistent = false, ?FFI\CDef $cdef = null): ?FFI\CData {} @@ -64,9 +64,9 @@ public static function string(FFI\CData $ptr, ?int $size = null): string {} /** @prefer-ref $ptr */ public static function isNull(FFI\CData $ptr): bool {} - public static function hasSymbol(FFI\CDef $cdef, $symbol, $type): bool {} + public static function hasSymbol(FFI\CDef $cdef, string $symbol, ?int $symbol_kind = null): bool {} - public static function getSymbols(FFI\CDef $cdef, $type): array {} + public static function getSymbols(FFI\CDef $cdef, ?int $symbol_kind = null): array {} } } diff --git a/ext/ffi/ffi_arginfo.h b/ext/ffi/ffi_arginfo.h index 1438c0283badc..640af0603bae4 100644 --- a/ext/ffi/ffi_arginfo.h +++ b/ext/ffi/ffi_arginfo.h @@ -1,16 +1,16 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d9dd3b93c0d1623fe61ea0bd8ee9d4c3a359bf78 */ + * Stub hash: 754463b45c9c4a1313e2bd690c84656d5d6ec853 */ -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_cdef, 0, 0, FFI, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_cdef, 0, 0, FFI\\CDef, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, code, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, lib, IS_STRING, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_load, 0, 1, FFI, 1) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_load, 0, 1, FFI\\CDef, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_scope, 0, 1, FFI, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_scope, 0, 1, FFI\\CDef, 0) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -18,6 +18,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_new, 0, 1, FFI\\CData, ZEND_ARG_OBJ_TYPE_MASK(0, type, FFI\\CType, MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, owned, _IS_BOOL, 0, "true") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent, _IS_BOOL, 0, "false") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, cdef, FFI\\CDef, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_FFI_free, 0, 1, IS_VOID, 0) @@ -27,10 +28,12 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_cast, 0, 2, FFI\\CData, 1) ZEND_ARG_OBJ_TYPE_MASK(0, type, FFI\\CType, MAY_BE_STRING, NULL) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, ptr) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, cdef, FFI\\CDef, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_type, 0, 1, FFI\\CType, 1) ZEND_ARG_TYPE_INFO(0, type, IS_STRING, 0) + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, cdef, FFI\\CDef, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_typeof, 0, 1, FFI\\CType, 0) @@ -79,6 +82,17 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_FFI_isNull, 0, 1, _IS_BOOL ZEND_ARG_OBJ_INFO(ZEND_SEND_PREFER_REF, ptr, FFI\\CData, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_FFI_hasSymbol, 0, 2, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, cdef, FFI\\CDef, 0) + ZEND_ARG_TYPE_INFO(0, symbol, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, symbol_kind, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_FFI_getSymbols, 0, 1, IS_ARRAY, 0) + ZEND_ARG_OBJ_INFO(0, cdef, FFI\\CDef, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, symbol_kind, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_FFI_CType_getName, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -139,6 +153,8 @@ ZEND_METHOD(FFI, memcmp); ZEND_METHOD(FFI, memset); ZEND_METHOD(FFI, string); ZEND_METHOD(FFI, isNull); +ZEND_METHOD(FFI, hasSymbol); +ZEND_METHOD(FFI, getSymbols); ZEND_METHOD(FFI_CType, getName); ZEND_METHOD(FFI_CType, getKind); ZEND_METHOD(FFI_CType, getSize); @@ -175,6 +191,13 @@ static const zend_function_entry class_FFI_methods[] = { ZEND_ME(FFI, memset, arginfo_class_FFI_memset, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(FFI, string, arginfo_class_FFI_string, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(FFI, isNull, arginfo_class_FFI_isNull, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(FFI, hasSymbol, arginfo_class_FFI_hasSymbol, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(FFI, getSymbols, arginfo_class_FFI_getSymbols, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_FE_END +}; + + +static const zend_function_entry class_FFI_CDef_methods[] = { ZEND_FE_END }; @@ -225,6 +248,17 @@ static zend_class_entry *register_class_FFI(void) return class_entry; } +static zend_class_entry *register_class_FFI_CDef(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "FFI", "CDef", class_FFI_CDef_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NOT_SERIALIZABLE; + + return class_entry; +} + static zend_class_entry *register_class_FFI_CData(void) { zend_class_entry ce, *class_entry; diff --git a/ext/ffi/tests/003.phpt b/ext/ffi/tests/003.phpt index d608c013d5a3b..e84c9858f0df1 100644 --- a/ext/ffi/tests/003.phpt +++ b/ext/ffi/tests/003.phpt @@ -25,17 +25,17 @@ struct _f; typedef struct _f f; EOF ); -var_dump($ffi->new("struct _a")); -var_dump($ffi->new("struct _b")); -var_dump($ffi->new("c")); -var_dump($ffi->new("d")); +var_dump(FFI::new("struct _a", cdef : $ffi)); +var_dump(FFI::new("struct _b", cdef : $ffi)); +var_dump(FFI::new("c", cdef : $ffi)); +var_dump(FFI::new("d", cdef : $ffi)); try { - var_dump($ffi->new("struct _e")); + var_dump(FFI::new("struct _e", cdef : $ffi)); } catch (Throwable $e) { echo get_class($e) . ": " . $e->getMessage()."\n"; } try { - var_dump($ffi->new("f")); + var_dump(FFI::new("f", cdef : $ffi)); } catch (Throwable $e) { echo get_class($e) . ": " . $e->getMessage()."\n"; } diff --git a/ext/ffi/tests/004.phpt b/ext/ffi/tests/004.phpt index 6852fe19ee75d..0fcb9b7a33f02 100644 --- a/ext/ffi/tests/004.phpt +++ b/ext/ffi/tests/004.phpt @@ -32,20 +32,20 @@ enum _g { }; EOF ); -var_dump($ffi->new("enum _a")); -var_dump($ffi->new("enum _b")); -var_dump($ffi->new("c")); -var_dump($ffi->new("d")); -var_dump($ffi->new("int[_c2]")); -var_dump($ffi->new("int[_c3]")); -var_dump($ffi->new("int[_c4]")); +var_dump(FFI::new("enum _a", cdef : $ffi)); +var_dump(FFI::new("enum _b", cdef : $ffi)); +var_dump(FFI::new("c", cdef : $ffi)); +var_dump(FFI::new("d", cdef : $ffi)); +var_dump(FFI::new("int[_c2]", cdef : $ffi)); +var_dump(FFI::new("int[_c3]", cdef : $ffi)); +var_dump(FFI::new("int[_c4]", cdef : $ffi)); try { - var_dump($ffi->new("enum _e")); + var_dump(FFI::new("enum _e", cdef : $ffi)); } catch (Throwable $e) { echo get_class($e) . ": " . $e->getMessage()."\n"; } try { - var_dump($ffi->new("f")); + var_dump(FFI::new("f", cdef : $ffi)); } catch (Throwable $e) { echo get_class($e) . ": " . $e->getMessage()."\n"; } diff --git a/ext/ffi/tests/020.phpt b/ext/ffi/tests/020.phpt index 1f510a0753b77..432f49ddfaf2d 100644 --- a/ext/ffi/tests/020.phpt +++ b/ext/ffi/tests/020.phpt @@ -52,7 +52,7 @@ try { } try { $f = FFI::cdef("typedef int * const t[1];"); - $p = $f->new("t"); + $p = FFI::new("t", cdef : $f); $p[0] = null; echo "ok\n"; } catch (Throwable $e) { diff --git a/ext/ffi/tests/029.phpt b/ext/ffi/tests/029.phpt index d6003c14a09f2..ec24b4e068e84 100644 --- a/ext/ffi/tests/029.phpt +++ b/ext/ffi/tests/029.phpt @@ -10,8 +10,8 @@ $ffi = FFI::cdef(" typedef char t1; typedef char _Alignas(int) t2; "); -var_dump(FFI::sizeof($ffi->new("struct {char a; t1 b;}"))); -var_dump(FFI::sizeof($ffi->new("struct {char a; t2 b;}"))); +var_dump(FFI::sizeof(FFI::new("struct {char a; t1 b;}", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("struct {char a; t2 b;}", cdef : $ffi))); ?> --EXPECT-- int(2) diff --git a/ext/ffi/tests/044.phpt b/ext/ffi/tests/044.phpt index 5f7b01ee60f3d..0819c79bef3f9 100644 --- a/ext/ffi/tests/044.phpt +++ b/ext/ffi/tests/044.phpt @@ -18,16 +18,16 @@ typedef unsigned int ud __attribute__ ((__mode__ (__DI__))); typedef float e __attribute__ ((__mode__ (__SF__))); typedef float f __attribute__ ((__mode__ (__DF__))); "); -var_dump(FFI::sizeof($ffi->new("a"))); -var_dump(FFI::sizeof($ffi->new("ua"))); -var_dump(FFI::sizeof($ffi->new("b"))); -var_dump(FFI::sizeof($ffi->new("ub"))); -var_dump(FFI::sizeof($ffi->new("c"))); -var_dump(FFI::sizeof($ffi->new("uc"))); -var_dump(FFI::sizeof($ffi->new("d"))); -var_dump(FFI::sizeof($ffi->new("ud"))); -var_dump(FFI::sizeof($ffi->new("e"))); -var_dump(FFI::sizeof($ffi->new("f"))); +var_dump(FFI::sizeof(FFI::new("a", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("ua", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("b", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("ub", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("c", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("uc", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("d", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("ud", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("e", cdef : $ffi))); +var_dump(FFI::sizeof(FFI::new("f", cdef : $ffi))); ?> --EXPECT-- int(1) diff --git a/ext/ffi/tests/100.phpt b/ext/ffi/tests/100.phpt index 33b974a37b183..c1e9f25afb843 100644 --- a/ext/ffi/tests/100.phpt +++ b/ext/ffi/tests/100.phpt @@ -34,7 +34,7 @@ var_dump(($zend->zend_printf)("Hello %s!\n", "World")); var_dump($zend->zend_hash_func("file", strlen("file"))); -$str = $zend->new("char[16]"); +$str = FFI::new("char[16]", cdef : $zend); FFI::memcpy($str, "Hello World!", strlen("Hello World!")); $zend->zend_str_tolower($str, strlen("Hello World!")); var_dump(FFI::string($str)); diff --git a/ext/ffi/tests/101.phpt b/ext/ffi/tests/101.phpt index 4730e2689e03b..caf19eb381baf 100644 --- a/ext/ffi/tests/101.phpt +++ b/ext/ffi/tests/101.phpt @@ -36,7 +36,7 @@ var_dump(($zend->zend_printf)("Hello %s!\n", "World")); $f = $zend->zend_hash_func; var_dump($f("file", strlen("file"))); -$str = $zend->new("char[16]"); +$str = FFI::new("char[16]", cdef : $zend); FFI::memcpy($str, "Hello World!", strlen("Hello World!")); $f = $zend->zend_str_tolower; $f($str, strlen("Hello World!")); diff --git a/ext/ffi/tests/bug77768.phpt b/ext/ffi/tests/bug77768.phpt index 90c38d7da75f2..fd672ee06520f 100644 --- a/ext/ffi/tests/bug77768.phpt +++ b/ext/ffi/tests/bug77768.phpt @@ -32,7 +32,7 @@ int printf(const char *format, ...); int printf(const char *format, ...); "); -var_dump(FFI::sizeof($x->new("uint8_t"))); +var_dump(FFI::sizeof(FFI::new("uint8_t", cdef : $x))); var_dump(FFI::sizeof(FFI::new("uint8_t"))); ?> --EXPECT-- diff --git a/ext/ffi/tests/bug78543.phpt b/ext/ffi/tests/bug78543.phpt index 7e4dee70623de..bb804b6a0420c 100644 --- a/ext/ffi/tests/bug78543.phpt +++ b/ext/ffi/tests/bug78543.phpt @@ -5,7 +5,7 @@ ffi --FILE-- new('struct test'); +$test = FFI::new('struct test', cdef : $ffi); var_dump(is_callable($test)); ?> --EXPECT-- diff --git a/ext/ffi/tests/bug79571.phpt b/ext/ffi/tests/bug79571.phpt index bc3b71fe17905..89c79af6790af 100644 --- a/ext/ffi/tests/bug79571.phpt +++ b/ext/ffi/tests/bug79571.phpt @@ -17,7 +17,7 @@ $ffi = FFI::cdef(<<new('my_union'); +$union = FFI::new('my_union', cdef : $ffi); $union->num = 42; var_dump($union); var_dump($union->num); diff --git a/ext/ffi/tests/bug80847.phpt b/ext/ffi/tests/bug80847.phpt index 83929de7512b4..a3a7469d98ef2 100644 --- a/ext/ffi/tests/bug80847.phpt +++ b/ext/ffi/tests/bug80847.phpt @@ -32,7 +32,7 @@ if (PHP_OS_FAMILY !== 'Windows') { $ffi = FFI::cdef($header, ffi_get_php_dll_name()); } } -$x = $ffi->new('bug80847_02'); +$x = FFI::new('bug80847_02', cdef : $ffi); $x->a->b = 42; $x->a->c = 42.5; var_dump($x); diff --git a/ext/ffi/tests/gh8433.phpt b/ext/ffi/tests/gh8433.phpt index 7c048fe1e5b80..3090f7cc606ed 100644 --- a/ext/ffi/tests/gh8433.phpt +++ b/ext/ffi/tests/gh8433.phpt @@ -8,9 +8,9 @@ ffi.enable=1 new("bar(*)(void)"); +$x = FFI::new("bar(*)(void)", cdef : $ffi); FFI::addr($x)[0] = function() use ($ffi) { - $bar = $ffi->new("bar"); + $bar = FFI::new("bar", cdef : $ffi); $bar->a = 2; return $bar; }; diff --git a/ext/ffi/tests/list.phpt b/ext/ffi/tests/list.phpt index cd4bb1f768f5c..802b52c91e951 100644 --- a/ext/ffi/tests/list.phpt +++ b/ext/ffi/tests/list.phpt @@ -22,7 +22,7 @@ class DList { }; "); } - $node = FFI::addr(self::$ffi->new("dlist", false)); + $node = FFI::addr(FFI::new("dlist", false, cdef : self::$ffi)); $node->data = 0; $node->next = $node; $node->prev = $node; @@ -41,7 +41,7 @@ class DList { } function add(int $data) { - $node = FFI::addr(self::$ffi->new("dlist", false)); + $node = FFI::addr(FFI::new("dlist", false, cdef : self::$ffi)); $node->data = $data; $node->next = $this->root; $node->prev = $this->root->prev; From d8340f6643c9ea309a07253f0dff50ca1c5084c9 Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 15:18:07 +0800 Subject: [PATCH 08/14] update --- ext/ffi/tests/047.phpt | 26 ++++++++++++++++++++++++++ ext/ffi/tests/048.phpt | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 ext/ffi/tests/047.phpt create mode 100644 ext/ffi/tests/048.phpt diff --git a/ext/ffi/tests/047.phpt b/ext/ffi/tests/047.phpt new file mode 100644 index 0000000000000..9a76c63d6ed80 --- /dev/null +++ b/ext/ffi/tests/047.phpt @@ -0,0 +1,26 @@ +--TEST-- +FFI 046: FFI::hasSymbol() +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- + +ok +--EXPECT-- +bool(true) +bool(true) +bool(false) +ok \ No newline at end of file diff --git a/ext/ffi/tests/048.phpt b/ext/ffi/tests/048.phpt new file mode 100644 index 0000000000000..55fa830a6fa8b --- /dev/null +++ b/ext/ffi/tests/048.phpt @@ -0,0 +1,35 @@ +--TEST-- +FFI 046: FFI::getSymbols() +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- + +ok +--EXPECT-- +array(1) { + ["type1"]=> + object(FFI\CType:int32_t)#2 (0) { + } +} +array(1) { + ["type1"]=> + object(FFI\CType:int32_t)#3 (0) { + } +} +array(0) { +} +ok \ No newline at end of file From a5dc8b6a0cfa20f2065db006a9217a836d47775b Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 16:05:17 +0800 Subject: [PATCH 09/14] update --- ext/ffi/ffi.c | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 2cafbc124c030..ff17d28b27307 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -201,11 +201,6 @@ static zend_object_handlers zend_ffi_cdata_value_handlers; static zend_object_handlers zend_ffi_cdata_free_handlers; static zend_object_handlers zend_ffi_ctype_handlers; -/* -static zend_internal_function zend_ffi_new_fn; -static zend_internal_function zend_ffi_cast_fn; -static zend_internal_function zend_ffi_type_fn; -*/ /* forward declarations */ static void _zend_ffi_type_dtor(zend_ffi_type *type); static void zend_ffi_finalize_type(zend_ffi_dcl *dcl); @@ -2223,6 +2218,8 @@ static zend_object *zend_ffi_new(zend_class_entry *class_type) /* {{{ */ { zend_object *ffi_obj; + ffi_obj = emalloc(sizeof(zend_ffi)); + zend_ffi_object_init(ffi_obj, class_type); ffi_obj->handlers = &zend_ffi_handlers; @@ -2823,26 +2820,7 @@ static zend_function *zend_ffi_get_func(zend_object **obj, zend_string *name, co zend_ffi_symbol *sym = NULL; zend_function *func; zend_ffi_type *type; - /* - if (ZSTR_LEN(name) == sizeof("new") -1 - && (ZSTR_VAL(name)[0] == 'n' || ZSTR_VAL(name)[0] == 'N') - && (ZSTR_VAL(name)[1] == 'e' || ZSTR_VAL(name)[1] == 'E') - && (ZSTR_VAL(name)[2] == 'w' || ZSTR_VAL(name)[2] == 'W')) { - return (zend_function*)&zend_ffi_new_fn; - } else if (ZSTR_LEN(name) == sizeof("cast") -1 - && (ZSTR_VAL(name)[0] == 'c' || ZSTR_VAL(name)[0] == 'C') - && (ZSTR_VAL(name)[1] == 'a' || ZSTR_VAL(name)[1] == 'A') - && (ZSTR_VAL(name)[2] == 's' || ZSTR_VAL(name)[2] == 'S') - && (ZSTR_VAL(name)[3] == 't' || ZSTR_VAL(name)[3] == 'T')) { - return (zend_function*)&zend_ffi_cast_fn; - } else if (ZSTR_LEN(name) == sizeof("type") -1 - && (ZSTR_VAL(name)[0] == 't' || ZSTR_VAL(name)[0] == 'T') - && (ZSTR_VAL(name)[1] == 'y' || ZSTR_VAL(name)[1] == 'Y') - && (ZSTR_VAL(name)[2] == 'p' || ZSTR_VAL(name)[2] == 'P') - && (ZSTR_VAL(name)[3] == 'e' || ZSTR_VAL(name)[3] == 'E')) { - return (zend_function*)&zend_ffi_type_fn; - } - */ + if (ffi->symbols) { sym = zend_hash_find_ptr(ffi->symbols, name); if (sym && sym->kind != ZEND_FFI_SYM_FUNC) { @@ -5368,14 +5346,6 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_ce = register_class_FFI(); zend_ffi_ce->create_object = zend_ffi_new; - /* - memcpy(&zend_ffi_new_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "new", sizeof("new")-1), sizeof(zend_internal_function)); - zend_ffi_new_fn.fn_flags &= ~ZEND_ACC_STATIC; - memcpy(&zend_ffi_cast_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "cast", sizeof("cast")-1), sizeof(zend_internal_function)); - zend_ffi_cast_fn.fn_flags &= ~ZEND_ACC_STATIC; - memcpy(&zend_ffi_type_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "type", sizeof("type")-1), sizeof(zend_internal_function)); - zend_ffi_type_fn.fn_flags &= ~ZEND_ACC_STATIC; - */ memcpy(&zend_ffi_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); zend_ffi_handlers.get_constructor = zend_fake_get_constructor; From c84c53f420125f96fc6d1e5a116e7bb2f807d070 Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 16:09:00 +0800 Subject: [PATCH 10/14] update --- ext/ffi/ffi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index ff17d28b27307..8ac2889c0c94c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -3682,7 +3682,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (type_def) { zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; - if (Z_TYPE_P(cdef) == IS_OBJECT) { + if (cdef && Z_TYPE_P(cdef) == IS_OBJECT) { zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(cdef); FFI_G(symbols) = ffi->symbols; FFI_G(tags) = ffi->tags; @@ -3695,7 +3695,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3715,7 +3715,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ is_const = 1; } - if (Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -3842,7 +3842,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3862,7 +3862,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ is_const = 1; } - if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -4011,7 +4011,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); From 8604991dc4170f3d733ba906732326670c079c66 Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 17:49:44 +0800 Subject: [PATCH 11/14] update --- ext/ffi/ffi.c | 18 +++++++------- ext/ffi/tests/048.phpt | 53 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 8ac2889c0c94c..937220a0b1730 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -3655,7 +3655,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ zend_object *type_obj = NULL; zend_ffi_type *type, *type_ptr; zend_ffi_cdata *cdata; - zval *cdef; + zval *cdef = NULL; void *ptr; bool owned = 1; bool persistent = 0; @@ -3695,7 +3695,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3715,7 +3715,7 @@ ZEND_METHOD(FFI, new) /* {{{ */ is_const = 1; } - if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -3810,7 +3810,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ zend_object *ztype = NULL; zend_ffi_type *old_type, *type, *type_ptr; zend_ffi_cdata *old_cdata, *cdata; - zval *cdef; + zval *cdef = NULL; bool is_const = 0; zval *zv, *arg; void *ptr; @@ -3842,7 +3842,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -3862,7 +3862,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */ is_const = 1; } - if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } @@ -3989,7 +3989,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ zend_ffi_ctype *ctype; zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; zend_string *type_def; - zval *cdef; + zval *cdef = NULL; ZEND_FFI_VALIDATE_API_RESTRICTION(); ZEND_PARSE_PARAMETERS_START(1, 2) @@ -4011,7 +4011,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { zend_ffi_type_dtor(dcl.type); - if (!cdef || Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef) { if (FFI_G(tags)) { zend_hash_destroy(FFI_G(tags)); efree(FFI_G(tags)); @@ -4026,7 +4026,7 @@ ZEND_METHOD(FFI, type) /* {{{ */ return; } - if (!cdef && Z_TYPE_P(cdef) != IS_OBJECT) { + if (!cdef) { if (FFI_G(tags)) { zend_ffi_tags_cleanup(&dcl); } diff --git a/ext/ffi/tests/048.phpt b/ext/ffi/tests/048.phpt index 55fa830a6fa8b..c540e813339d8 100644 --- a/ext/ffi/tests/048.phpt +++ b/ext/ffi/tests/048.phpt @@ -11,25 +11,66 @@ ffi.enable=1 $ffi = FFI::cdef(<< ok ---EXPECT-- -array(1) { +--EXPECTF-- +array(6) { ["type1"]=> - object(FFI\CType:int32_t)#2 (0) { + object(FFI\CType:int32_t)#%d (0) { + } + ["type2"]=> + object(FFI\CType:char)#%d (0) { + } + ["_c1"]=> + object(FFI\CType:uint32_t)#%d (0) { + } + ["_c2"]=> + object(FFI\CType:uint32_t)#%d (0) { + } + ["_c3"]=> + object(FFI\CType:uint32_t)#%d (0) { + } + ["_c4"]=> + object(FFI\CType:uint32_t)#%d (0) { } } -array(1) { +array(2) { ["type1"]=> - object(FFI\CType:int32_t)#3 (0) { + object(FFI\CType:int32_t)#%d (0) { + } + ["type2"]=> + object(FFI\CType:char)#%d (0) { } } array(0) { } -ok \ No newline at end of file +array(4) { + ["_c1"]=> + object(FFI\CType:uint32_t)#%d (0) { + } + ["_c2"]=> + object(FFI\CType:uint32_t)#%d (0) { + } + ["_c3"]=> + object(FFI\CType:uint32_t)#%d (0) { + } + ["_c4"]=> + object(FFI\CType:uint32_t)#%d (0) { + } +} +ok From 63fe549a859a7dd4a572b8a1653e4a1578746277 Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 18:04:38 +0800 Subject: [PATCH 12/14] update --- ext/ffi/ffi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 937220a0b1730..5eeaaf9095f7b 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -4567,7 +4567,7 @@ ZEND_METHOD(FFI, getSymbols) /* {{{ */ zend_ffi_ctype *ctype = (zend_ffi_ctype*)zend_ffi_ctype_new(zend_ffi_ctype_ce); ctype->type = sym->type; - ZVAL_OBJ_COPY(&ctype_object, &ctype->std); + ZVAL_OBJ(&ctype_object, &ctype->std); zend_hash_add_new(Z_ARRVAL_P(return_value), name, &ctype_object); } ZEND_HASH_FOREACH_END(); } From 21673358bea141e73d2933bd9213a1977c77f6aa Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 20:56:46 +0800 Subject: [PATCH 13/14] update --- ext/ffi/tests/bug79177.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ffi/tests/bug79177.phpt b/ext/ffi/tests/bug79177.phpt index aaabfdbca012f..e97f708f45fa8 100644 --- a/ext/ffi/tests/bug79177.phpt +++ b/ext/ffi/tests/bug79177.phpt @@ -33,7 +33,7 @@ echo "done\n"; Warning: Uncaught RuntimeException: Not allowed in %s:%d Stack trace: #0 %s(%d): {closure}() -#1 %s(%d): FFI->bug79177() +#1 %s(%d): FFI\CDef->bug79177() #2 {main} thrown in %s on line %d From eae05ff9fb56acf6c71a7a4e48bc5431f34ff90d Mon Sep 17 00:00:00 2001 From: chopins Date: Fri, 20 May 2022 21:08:20 +0800 Subject: [PATCH 14/14] update --- ext/ffi/tests/047.phpt | 2 +- ext/ffi/tests/048.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ffi/tests/047.phpt b/ext/ffi/tests/047.phpt index 9a76c63d6ed80..8c368e3c12f6b 100644 --- a/ext/ffi/tests/047.phpt +++ b/ext/ffi/tests/047.phpt @@ -1,5 +1,5 @@ --TEST-- -FFI 046: FFI::hasSymbol() +FFI 047: FFI::hasSymbol() --EXTENSIONS-- ffi --INI-- diff --git a/ext/ffi/tests/048.phpt b/ext/ffi/tests/048.phpt index c540e813339d8..78b55ec4aad3f 100644 --- a/ext/ffi/tests/048.phpt +++ b/ext/ffi/tests/048.phpt @@ -1,5 +1,5 @@ --TEST-- -FFI 046: FFI::getSymbols() +FFI 048: FFI::getSymbols() --EXTENSIONS-- ffi --INI--