Skip to content

Commit 0128f6e

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: NEWS entry, test and minor cleanup for FFI::isNull() add FFI::isNull() to check whether a FFI\CData is a null pointer
2 parents 989959f + 21c3cdf commit 0128f6e

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

ext/ffi/ffi.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4329,6 +4329,35 @@ ZEND_METHOD(FFI, string) /* {{{ */
43294329
}
43304330
/* }}} */
43314331

4332+
ZEND_METHOD(FFI, isNull) /* {{{ */
4333+
{
4334+
zval *zv;
4335+
zend_ffi_cdata *cdata;
4336+
zend_ffi_type *type;
4337+
4338+
ZEND_FFI_VALIDATE_API_RESTRICTION();
4339+
ZEND_PARSE_PARAMETERS_START(1, 1)
4340+
Z_PARAM_ZVAL(zv);
4341+
ZEND_PARSE_PARAMETERS_END();
4342+
4343+
ZVAL_DEREF(zv);
4344+
if (Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != zend_ffi_cdata_ce) {
4345+
zend_wrong_parameter_class_error(1, "FFI\\CData", zv);
4346+
return;
4347+
}
4348+
4349+
cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
4350+
type = ZEND_FFI_TYPE(cdata->type);
4351+
4352+
if (type->kind != ZEND_FFI_TYPE_POINTER){
4353+
zend_throw_error(zend_ffi_exception_ce, "FFI\\Cdata is not a pointer");
4354+
return;
4355+
}
4356+
4357+
RETURN_BOOL(*(void**)cdata->ptr == NULL);
4358+
}
4359+
/* }}} */
4360+
43324361
static const zend_function_entry zend_ffi_functions[] = {
43334362
ZEND_ME(FFI, cdef, arginfo_class_FFI_cdef, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
43344363
ZEND_ME(FFI, load, arginfo_class_FFI_load, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
@@ -4346,6 +4375,7 @@ static const zend_function_entry zend_ffi_functions[] = {
43464375
ZEND_ME(FFI, memcmp, arginfo_class_FFI_memcmp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
43474376
ZEND_ME(FFI, memset, arginfo_class_FFI_memset, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
43484377
ZEND_ME(FFI, string, arginfo_class_FFI_string, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
4378+
ZEND_ME(FFI, isNull, arginfo_class_FFI_isNull, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
43494379
ZEND_FE_END
43504380
};
43514381

ext/ffi/ffi.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,9 @@ static function memset(FFI\CData $ptr, int $ch, int $size) {}
8888
* @return ?string
8989
*/
9090
static function string(FFI\CData $ptr, int $size = UNKNOWN) {}
91+
92+
/**
93+
* @prefer-ref $ptr
94+
*/
95+
static function isNull(FFI\CData $ptr) {}
9196
}

ext/ffi/ffi_arginfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,5 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_FFI_string, 0, 0, 1)
6969
ZEND_ARG_OBJ_INFO(ZEND_SEND_PREFER_REF, ptr, FFI\\CData, 0)
7070
ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0)
7171
ZEND_END_ARG_INFO()
72+
73+
#define arginfo_class_FFI_isNull arginfo_class_FFI_free

ext/ffi/tests/045.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
FFI 045: FFI::isNull()
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
var_dump(FFI::isNull(FFI::new("int*")));
10+
$i = FFI::new("int");
11+
var_dump(FFI::isNull(FFI::addr($i)));
12+
try {
13+
var_dump(FFI::isNull(null));
14+
} catch (Throwable $e) {
15+
echo get_class($e) . ": " . $e->getMessage()."\n";
16+
}
17+
try {
18+
var_dump(FFI::isNull(FFI::new("int[0]")));
19+
} catch (Throwable $e) {
20+
echo get_class($e) . ": " . $e->getMessage()."\n";
21+
}
22+
?>
23+
--EXPECTF--
24+
bool(true)
25+
bool(false)
26+
TypeError: FFI::isNull() expects parameter 1 to be FFI\CData, null given
27+
FFI\Exception: FFI\Cdata is not a pointer

0 commit comments

Comments
 (0)