diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index d797f5f93f809..4849527b1d42c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -4336,6 +4336,34 @@ ZEND_METHOD(FFI, addr) /* {{{ */ } /* }}} */ +ZEND_METHOD(FFI, addrValue) /* {{{ */ +{ + zval *zv; + zend_ffi_cdata *cdata; + zend_ffi_type *type; + + ZEND_FFI_VALIDATE_API_RESTRICTION(); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(zv); + ZEND_PARSE_PARAMETERS_END(); + + ZVAL_DEREF(zv); + + if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == zend_ffi_cdata_ce) { + cdata = (zend_ffi_cdata*)Z_OBJ_P(zv); + type = ZEND_FFI_TYPE(cdata->type); + if (EXPECTED(type->kind != ZEND_FFI_TYPE_POINTER)) { + zend_throw_error(zend_ffi_exception_ce, "FFI\\Cdata is not a pointer"); + RETURN_THROWS(); + } + RETURN_LONG((zend_long)cdata->ptr_holder); + } else { + zend_wrong_parameter_class_error(1, "FFI\\CData", zv); + RETURN_THROWS(); + } +} +/* }}} */ + ZEND_METHOD(FFI, sizeof) /* {{{ */ { zval *zv; diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php index 0ed3cb32ac6ed..651fcdc05cc41 100644 --- a/ext/ffi/ffi.stub.php +++ b/ext/ffi/ffi.stub.php @@ -65,6 +65,9 @@ public static function string(FFI\CData $ptr, ?int $size = null): string {} /** @prefer-ref $ptr */ public static function isNull(FFI\CData $ptr): bool {} + + /** @prefer-ref $ptr */ + public static function addrValue(FFI\CData $ptr): int {} } } diff --git a/ext/ffi/ffi_arginfo.h b/ext/ffi/ffi_arginfo.h index aca7a8d25637c..12e992f24e40e 100644 --- a/ext/ffi/ffi_arginfo.h +++ b/ext/ffi/ffi_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1255ed4477be5b4361622aab54ebe37f42b1dada */ + * Stub hash: 373cc1a2bc26b100e0d54f734bc38d2619651761 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_cdef, 0, 0, FFI, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, code, IS_STRING, 0, "\"\"") @@ -79,6 +79,10 @@ 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_addrValue, 0, 1, IS_LONG, 0) + 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_CType_getName, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -138,6 +142,7 @@ ZEND_METHOD(FFI, memcmp); ZEND_METHOD(FFI, memset); ZEND_METHOD(FFI, string); ZEND_METHOD(FFI, isNull); +ZEND_METHOD(FFI, addrValue); ZEND_METHOD(FFI_CType, getName); ZEND_METHOD(FFI_CType, getKind); ZEND_METHOD(FFI_CType, getSize); @@ -173,6 +178,7 @@ 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, addrValue, arginfo_class_FFI_addrValue, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END }; diff --git a/ext/ffi/tests/048.phpt b/ext/ffi/tests/048.phpt new file mode 100644 index 0000000000000..82bf400a17a1d --- /dev/null +++ b/ext/ffi/tests/048.phpt @@ -0,0 +1,19 @@ +--TEST-- +FFI 048: CData::addrValue() get the value of the pointer variable +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +cast("void*", 20); +$v = FFI::addrValue($x); +var_dump($v); + +$x2 = FFI::cdef()->cast('int*', 30); +$v2 = FFI::addrValue($x2); +var_dump($v2); +?> +--EXPECTF-- +int(20) +int(30)