Deprecate calling FFI::cast(), FFI::new(), and FFI::type() statically

This commit is contained in:
Máté Kocsis 2023-07-01 13:37:11 +02:00
parent 134441efa9
commit 4acf0084dc
47 changed files with 311 additions and 110 deletions

View file

@ -3736,6 +3736,7 @@ ZEND_METHOD(FFI, new) /* {{{ */
bool owned = 1; bool owned = 1;
bool persistent = 0; bool persistent = 0;
bool is_const = 0; bool is_const = 0;
bool is_static_call = Z_TYPE(EX(This)) != IS_OBJECT;
zend_ffi_flags flags = ZEND_FFI_FLAG_OWNED; zend_ffi_flags flags = ZEND_FFI_FLAG_OWNED;
ZEND_FFI_VALIDATE_API_RESTRICTION(); ZEND_FFI_VALIDATE_API_RESTRICTION();
@ -3746,6 +3747,13 @@ ZEND_METHOD(FFI, new) /* {{{ */
Z_PARAM_BOOL(persistent) Z_PARAM_BOOL(persistent)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
if (is_static_call) {
zend_error(E_DEPRECATED, "Calling FFI::new() statically is deprecated");
if (EG(exception)) {
RETURN_THROWS();
}
}
if (!owned) { if (!owned) {
flags &= ~ZEND_FFI_FLAG_OWNED; flags &= ~ZEND_FFI_FLAG_OWNED;
} }
@ -3757,7 +3765,7 @@ ZEND_METHOD(FFI, new) /* {{{ */
if (type_def) { if (type_def) {
zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT;
if (Z_TYPE(EX(This)) == IS_OBJECT) { if (!is_static_call) {
zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This)); zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This));
FFI_G(symbols) = ffi->symbols; FFI_G(symbols) = ffi->symbols;
FFI_G(tags) = ffi->tags; FFI_G(tags) = ffi->tags;
@ -3770,7 +3778,7 @@ ZEND_METHOD(FFI, new) /* {{{ */
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
zend_ffi_type_dtor(dcl.type); zend_ffi_type_dtor(dcl.type);
if (Z_TYPE(EX(This)) != IS_OBJECT) { if (is_static_call) {
if (FFI_G(tags)) { if (FFI_G(tags)) {
zend_hash_destroy(FFI_G(tags)); zend_hash_destroy(FFI_G(tags));
efree(FFI_G(tags)); efree(FFI_G(tags));
@ -3790,7 +3798,7 @@ ZEND_METHOD(FFI, new) /* {{{ */
is_const = 1; is_const = 1;
} }
if (Z_TYPE(EX(This)) != IS_OBJECT) { if (is_static_call) {
if (FFI_G(tags)) { if (FFI_G(tags)) {
zend_ffi_tags_cleanup(&dcl); zend_ffi_tags_cleanup(&dcl);
} }
@ -3886,6 +3894,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */
zend_ffi_type *old_type, *type, *type_ptr; zend_ffi_type *old_type, *type, *type_ptr;
zend_ffi_cdata *old_cdata, *cdata; zend_ffi_cdata *old_cdata, *cdata;
bool is_const = 0; bool is_const = 0;
bool is_static_call = Z_TYPE(EX(This)) != IS_OBJECT;
zval *zv, *arg; zval *zv, *arg;
void *ptr; void *ptr;
@ -3895,13 +3904,20 @@ ZEND_METHOD(FFI, cast) /* {{{ */
Z_PARAM_ZVAL(zv) Z_PARAM_ZVAL(zv)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
if (is_static_call) {
zend_error(E_DEPRECATED, "Calling FFI::cast() statically is deprecated");
if (EG(exception)) {
RETURN_THROWS();
}
}
arg = zv; arg = zv;
ZVAL_DEREF(zv); ZVAL_DEREF(zv);
if (type_def) { if (type_def) {
zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT;
if (Z_TYPE(EX(This)) == IS_OBJECT) { if (!is_static_call) {
zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This)); zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This));
FFI_G(symbols) = ffi->symbols; FFI_G(symbols) = ffi->symbols;
FFI_G(tags) = ffi->tags; FFI_G(tags) = ffi->tags;
@ -3914,7 +3930,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
zend_ffi_type_dtor(dcl.type); zend_ffi_type_dtor(dcl.type);
if (Z_TYPE(EX(This)) != IS_OBJECT) { if (is_static_call) {
if (FFI_G(tags)) { if (FFI_G(tags)) {
zend_hash_destroy(FFI_G(tags)); zend_hash_destroy(FFI_G(tags));
efree(FFI_G(tags)); efree(FFI_G(tags));
@ -3934,7 +3950,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */
is_const = 1; is_const = 1;
} }
if (Z_TYPE(EX(This)) != IS_OBJECT) { if (is_static_call) {
if (FFI_G(tags)) { if (FFI_G(tags)) {
zend_ffi_tags_cleanup(&dcl); zend_ffi_tags_cleanup(&dcl);
} }
@ -4061,13 +4077,21 @@ ZEND_METHOD(FFI, type) /* {{{ */
zend_ffi_ctype *ctype; zend_ffi_ctype *ctype;
zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT; zend_ffi_dcl dcl = ZEND_FFI_ATTR_INIT;
zend_string *type_def; zend_string *type_def;
bool is_static_call = Z_TYPE(EX(This)) != IS_OBJECT;
ZEND_FFI_VALIDATE_API_RESTRICTION(); ZEND_FFI_VALIDATE_API_RESTRICTION();
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(type_def); Z_PARAM_STR(type_def);
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
if (Z_TYPE(EX(This)) == IS_OBJECT) { if (is_static_call) {
zend_error(E_DEPRECATED, "Calling FFI::type() statically is deprecated");
if (EG(exception)) {
RETURN_THROWS();
}
}
if (!is_static_call) {
zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This)); zend_ffi *ffi = (zend_ffi*)Z_OBJ(EX(This));
FFI_G(symbols) = ffi->symbols; FFI_G(symbols) = ffi->symbols;
FFI_G(tags) = ffi->tags; FFI_G(tags) = ffi->tags;
@ -4080,7 +4104,7 @@ ZEND_METHOD(FFI, type) /* {{{ */
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) { if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
zend_ffi_type_dtor(dcl.type); zend_ffi_type_dtor(dcl.type);
if (Z_TYPE(EX(This)) != IS_OBJECT) { if (is_static_call) {
if (FFI_G(tags)) { if (FFI_G(tags)) {
zend_hash_destroy(FFI_G(tags)); zend_hash_destroy(FFI_G(tags));
efree(FFI_G(tags)); efree(FFI_G(tags));
@ -4095,7 +4119,7 @@ ZEND_METHOD(FFI, type) /* {{{ */
return; return;
} }
if (Z_TYPE(EX(This)) != IS_OBJECT) { if (is_static_call) {
if (FFI_G(tags)) { if (FFI_G(tags)) {
zend_ffi_tags_cleanup(&dcl); zend_ffi_tags_cleanup(&dcl);
} }

View file

@ -6,8 +6,10 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$m = FFI::new("int[2][2]"); $ffi = FFI::cdef();
$v = FFI::new("int[2]");
$m = $ffi->new("int[2][2]");
$v = $ffi->new("int[2]");
$v[1] = 42; $v[1] = 42;
$m[1] = $v; $m[1] = $v;
var_dump($m); var_dump($m);

View file

@ -6,8 +6,10 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$v = FFI::new("int*[2]"); $ffi = FFI::cdef();
$v[1] = FFI::new("int[1]", false);
$v = $ffi->new("int*[2]");
$v[1] = $ffi->new("int[1]", false);
$v[1][0] = 42; $v[1][0] = 42;
var_dump($v); var_dump($v);
FFI::free($v[1]); FFI::free($v[1]);

View file

@ -6,9 +6,11 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$v = FFI::new("int*[3]"); $ffi = FFI::cdef();
$v[0] = FFI::new("int[1]", false);
$v[1] = FFI::new("int[1]", false); $v = $ffi->new("int*[3]");
$v[0] = $ffi->new("int[1]", false);
$v[1] = $ffi->new("int[1]", false);
$v[2] = $v[1]; $v[2] = $v[1];
$v[1][0] = 42; $v[1][0] = 42;
var_dump($v[0] == $v[1]); var_dump($v[0] == $v[1]);

View file

@ -6,7 +6,9 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[3]"); $ffi = FFI::cdef();
$a = $ffi->new("int[3]");
$a[1] = 10; $a[1] = 10;
$a[2] = 20; $a[2] = 20;
var_dump(count($a)); var_dump(count($a));
@ -14,7 +16,7 @@ foreach ($a as $key => $val) {
echo "$key => $val\n"; echo "$key => $val\n";
} }
$a = FFI::new("struct {int x,y;}"); $a = $ffi->new("struct {int x,y;}");
try { try {
var_dump(count($a)); var_dump(count($a));
} catch (Throwable $e) { } catch (Throwable $e) {

View file

@ -6,10 +6,12 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[3]"); $ffi = FFI::cdef();
$a = $ffi->new("int[3]");
$a[1] = 10; $a[1] = 10;
$a[2] = 20; $a[2] = 20;
$b = FFI::new("int[4]"); $b = $ffi->new("int[4]");
var_dump(FFI::memcmp($b, $a, FFI::sizeof($a))); var_dump(FFI::memcmp($b, $a, FFI::sizeof($a)));
FFI::memcpy($b, $a, FFI::sizeof($a)); FFI::memcpy($b, $a, FFI::sizeof($a));
var_dump($b); var_dump($b);

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[3]"); $a = FFI::cdef()->new("int[3]");
FFI::memset($a, ord("a"), FFI::sizeof($a)); FFI::memset($a, ord("a"), FFI::sizeof($a));
var_dump(FFI::string($a, FFI::sizeof($a))); var_dump(FFI::string($a, FFI::sizeof($a)));
?> ?>

View file

@ -6,10 +6,12 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("uint8_t[4]"); $ffi = FFI::cdef();
$a = $ffi->new("uint8_t[4]");
$a[0] = 255; $a[0] = 255;
$a[1] = 255; $a[1] = 255;
var_dump(FFI::cast("uint16_t[2]", $a)); var_dump($ffi->cast("uint16_t[2]", $a));
?> ?>
--EXPECTF-- --EXPECTF--
object(FFI\CData:uint16_t[2])#%d (2) { object(FFI\CData:uint16_t[2])#%d (2) {

View file

@ -7,7 +7,7 @@ ffi.enable=1
--FILE-- --FILE--
<?php <?php
try { try {
var_dump(serialize(FFI::new("int[2]"))); var_dump(serialize(FFI::cdef()->new("int[2]")));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }

View file

@ -6,19 +6,21 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[1][2][3]"); $ffi = FFI::cdef();
$a = $ffi->new("int[1][2][3]");
var_dump(count($a)); var_dump(count($a));
var_dump(count($a[0])); var_dump(count($a[0]));
var_dump(count($a[0][0])); var_dump(count($a[0][0]));
try { try {
var_dump(FFI::new("void")); var_dump($ffi->new("void"));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
var_dump(FFI::new("void[1]")); var_dump($ffi->new("void[1]"));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }

View file

@ -6,9 +6,11 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
var_dump(FFI::sizeof(FFI::new("uint32_t[2]"))); $ffi = FFI::cdef();
var_dump(FFI::sizeof(FFI::new("uint32_t([2])")));
var_dump(FFI::sizeof(FFI::new("uint32_t([2])[2]"))); var_dump(FFI::sizeof($ffi->new("uint32_t[2]")));
var_dump(FFI::sizeof($ffi->new("uint32_t([2])")));
var_dump(FFI::sizeof($ffi->new("uint32_t([2])[2]")));
?> ?>
ok ok
--EXPECT-- --EXPECT--

View file

@ -24,8 +24,13 @@ try {
?> ?>
ok ok
--EXPECTF-- --EXPECTF--
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
FFI\ParserException: function type is not allowed at line 1 FFI\ParserException: function type is not allowed at line 1
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
FFI\ParserException: Struct/union can't contain an instance of itself at line 1 FFI\ParserException: Struct/union can't contain an instance of itself at line 1
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
object(FFI\CData:struct X)#%d (1) { object(FFI\CData:struct X)#%d (1) {
["ptr"]=> ["ptr"]=>
NULL NULL

View file

@ -6,8 +6,10 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$ffi = FFI::cdef();
try { try {
$p = FFI::new("struct {int x; const int y;}"); $p = $ffi->new("struct {int x; const int y;}");
$p->x = 1; $p->x = 1;
$p->y = 1; $p->y = 1;
echo "ok\n"; echo "ok\n";
@ -15,7 +17,7 @@ try {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
$p = FFI::new("struct {const int x; int y;}"); $p = $ffi->new("struct {const int x; int y;}");
$p->y = 1; $p->y = 1;
$p->x = 1; $p->x = 1;
echo "ok\n"; echo "ok\n";
@ -23,28 +25,28 @@ try {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
$p = FFI::new("const struct {int x; int y;}"); $p = $ffi->new("const struct {int x; int y;}");
$p->x = 1; $p->x = 1;
echo "ok\n"; echo "ok\n";
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
$p = FFI::new("const int[10]"); $p = $ffi->new("const int[10]");
$p[1] = 1; $p[1] = 1;
echo "ok\n"; echo "ok\n";
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
$p = FFI::new("const int * [1]"); $p = $ffi->new("const int * [1]");
$p[0] = null; $p[0] = null;
echo "ok\n"; echo "ok\n";
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
$p = FFI::new("int * const [1]"); $p = $ffi->new("int * const [1]");
$p[0] = null; $p[0] = null;
echo "ok\n"; echo "ok\n";
} catch (Throwable $e) { } catch (Throwable $e) {

View file

@ -53,5 +53,66 @@ test(4, "enum __attribute__((packed)) {a14=-0x80000000}");
test(8, "enum __attribute__((packed)) {a14=-0x80000001}"); test(8, "enum __attribute__((packed)) {a14=-0x80000001}");
?> ?>
ok ok
--EXPECT-- --EXPECTF--
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
ok ok

View file

@ -7,13 +7,13 @@ ffi.enable=1
--FILE-- --FILE--
<?php <?php
function test_size($size, $type) { function test_size($size, $type) {
if (FFI::sizeof(FFI::new($type)) !== $size) { if (FFI::sizeof(FFI::cdef()->new($type)) !== $size) {
echo "FAIL: sizeof($type) != $size\n"; echo "FAIL: sizeof($type) != $size\n";
} }
} }
function test_align($align, $type) { function test_align($align, $type) {
if (FFI::alignof(FFI::new($type)) !== $align) { if (FFI::alignof(FFI::cdef()->new($type)) !== $align) {
echo "FAIL: alignof($type) != $align\n"; echo "FAIL: alignof($type) != $align\n";
} }
} }

View file

@ -6,13 +6,15 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$ffi = FFI::cdef();
try { try {
var_dump(FFI::sizeof(FFI::new("struct {}"))); var_dump(FFI::sizeof($ffi->new("struct {}")));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage() . "\n"; echo get_class($e) . ": " . $e->getMessage() . "\n";
} }
var_dump(FFI::sizeof(FFI::new("struct {int a}"))); var_dump(FFI::sizeof($ffi->new("struct {int a}")));
var_dump(FFI::sizeof(FFI::new("struct {int a; int b}"))); var_dump(FFI::sizeof($ffi->new("struct {int a; int b}")));
?> ?>
ok ok
--EXPECT-- --EXPECT--

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$p = FFI::new(" $p = FFI::cdef()->new("
struct { struct {
int a; int a;
struct { struct {

View file

@ -6,7 +6,9 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$x = FFI::new("int"); $ffi = FFI::cdef();
$x = $ffi->new("int");
$x->cdata = 5; $x->cdata = 5;
var_dump($x); var_dump($x);
$x->cdata += 2; $x->cdata += 2;
@ -14,7 +16,7 @@ ffi.enable=1
echo "$x\n\n"; echo "$x\n\n";
unset($x); unset($x);
$x = FFI::new("char"); $x = $ffi->new("char");
$x->cdata = 'a'; $x->cdata = 'a';
var_dump($x); var_dump($x);
$x->cdata++; $x->cdata++;

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[3]"); $a = FFI::cdef()->new("int[3]");
$a[1] = 10; $a[1] = 10;
$a[2] = 20; $a[2] = 20;
var_dump($a); var_dump($a);

View file

@ -6,8 +6,10 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$ffi = FFI::cdef();
try { try {
$p = FFI::new("int[*]"); $p = $ffi->new("int[*]");
echo "ok\n"; echo "ok\n";
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
@ -31,17 +33,17 @@ try {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
var_dump(FFI::sizeof(FFI::new("int[0]"))); var_dump(FFI::sizeof($ffi->new("int[0]")));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
var_dump(FFI::sizeof(FFI::new("int[]"))); var_dump(FFI::sizeof($ffi->new("int[]")));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
var_dump(FFI::sizeof(FFI::cast("int[]", FFI::new("int[2]")))); var_dump(FFI::sizeof($ffi->cast("int[]", $ffi->new("int[2]"))));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }

View file

@ -6,8 +6,10 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
var_dump(FFI::sizeof(FFI::new("bool[2]"))); $ffi = FFI::cdef();
$p = FFI::new("bool[2]");
var_dump(FFI::sizeof($ffi->new("bool[2]")));
$p = $ffi->new("bool[2]");
var_dump($p); var_dump($p);
$p[1] = true; $p[1] = true;
var_dump($p[0]); var_dump($p[0]);

View file

@ -8,7 +8,7 @@ ffi.enable=1
<?php <?php
function test_size($expected_size, $type) { function test_size($expected_size, $type) {
try { try {
$size = FFI::sizeof(FFI::new($type)); $size = FFI::sizeof(FFI::cdef()->new($type));
if ($size !== $expected_size) { if ($size !== $expected_size) {
echo "FAIL: sizeof($type) != $expected_size ($size)\n"; echo "FAIL: sizeof($type) != $expected_size ($size)\n";
} }

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$p = FFI::new(" $p = FFI::cdef()->new("
union { union {
struct __attribute__((packed)) { struct __attribute__((packed)) {
int a:2; int a:2;

View file

@ -6,22 +6,24 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$p1 = FFI::new("uint8_t[2]"); $ffi = FFI::cdef();
$p2 = FFI::new("uint16_t[2]", true, true);
$p1 = $ffi->new("uint8_t[2]");
$p2 = $ffi->new("uint16_t[2]", true, true);
var_dump($p1, $p2); var_dump($p1, $p2);
$t1 = FFI::typeof($p1); $t1 = FFI::typeof($p1);
var_dump($t1); var_dump($t1);
$p4 = FFI::new($t1); $p4 = $ffi->new($t1);
var_dump($p4); var_dump($p4);
$t2 = FFI::type("uint16_t[2]"); $t2 = $ffi->type("uint16_t[2]");
var_dump($t2); var_dump($t2);
$p4 = FFI::new($t2); $p4 = $ffi->new($t2);
var_dump($p4); var_dump($p4);
$t2 = FFI::type("uint32_t"); $t2 = $ffi->type("uint32_t");
var_dump($t2); var_dump($t2);
$t3 = FFI::arrayType($t2, [2, 2]); $t3 = FFI::arrayType($t2, [2, 2]);
var_dump($t3); var_dump($t3);

View file

@ -6,9 +6,11 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$p1 = FFI::new("uint8_t[2]"); $ffi = FFI::cdef();
$p2 = FFI::new("uint16_t[2]");
$p3 = FFI::new("uint32_t[2]"); $p1 = $ffi->new("uint8_t[2]");
$p2 = $ffi->new("uint16_t[2]");
$p3 = $ffi->new("uint32_t[2]");
var_dump(FFI::sizeof($p1), FFI::sizeof($p2), FFI::sizeof($p3)); var_dump(FFI::sizeof($p1), FFI::sizeof($p2), FFI::sizeof($p3));
var_dump(FFI::alignof($p1), FFI::alignof($p2), FFI::alignof($p3)); var_dump(FFI::alignof($p1), FFI::alignof($p2), FFI::alignof($p3));
var_dump(FFI::sizeof(FFI::typeof($p1)), FFI::sizeof(FFI::typeof($p2)), FFI::sizeof(FFI::typeof($p3))); var_dump(FFI::sizeof(FFI::typeof($p1)), FFI::sizeof(FFI::typeof($p2)), FFI::sizeof(FFI::typeof($p3)));

View file

@ -1,12 +1,12 @@
--TEST-- --TEST--
FFI 035: FFI::new() not-owned FFI 035: FFI::cdef()->new() not-owned
--EXTENSIONS-- --EXTENSIONS--
ffi ffi
--INI-- --INI--
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$p = FFI::new("uint16_t[2]", false); $p = FFI::cdef()->new("uint16_t[2]", false);
var_dump($p); var_dump($p);
FFI::free($p); FFI::free($p);

View file

@ -6,18 +6,21 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$type = FFI::type("int*"); $ffi = FFI::cdef();
$type = $ffi->type("int*");
function foo($ptr) { function foo($ptr) {
global $type; global $type;
//$buf = FFI::new("int*[1]"); /* this loses type and crash */ global $ffi;
$buf = FFI::new(FFI::arrayType($type, [1])); //$buf = $ffi->new("int*[1]"); /* this loses type and crash */
$buf = $ffi->new(FFI::arrayType($type, [1]));
$buf[0] = $ptr; $buf[0] = $ptr;
//... //...
return $buf[0]; return $buf[0];
} }
$int = FFI::new("int"); $int = $ffi->new("int");
$int->cdata = 42; $int->cdata = 42;
var_dump(foo(FFI::addr($int))); var_dump(foo(FFI::addr($int)));
?> ?>

View file

@ -7,13 +7,13 @@ ffi.enable=1
--FILE-- --FILE--
<?php <?php
function foo($ptr) { function foo($ptr) {
$buf = FFI::new("int*[1]"); $buf = FFI::cdef()->new("int*[1]");
$buf[0] = $ptr; $buf[0] = $ptr;
//... //...
return $buf[0]; return $buf[0];
} }
$int = FFI::new("int"); $int = FFI::cdef()->new("int");
$int->cdata = 42; $int->cdata = 42;
var_dump(foo(FFI::addr($int))); var_dump(foo(FFI::addr($int)));
?> ?>

View file

@ -6,11 +6,13 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[10]"); $ffi = FFI::cdef();
$a = $ffi->new("int[10]");
for ($i = 0; $i < 10; $i++) { for ($i = 0; $i < 10; $i++) {
$a[$i] = $i; $a[$i] = $i;
} }
$p = FFI::cast("int*", $a); $p = $ffi->cast("int*", $a);
var_dump($p[0]); var_dump($p[0]);
var_dump($p[2]); var_dump($p[2]);
vaR_dump($p) vaR_dump($p)

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("int[10]"); $a = FFI::cdef()->new("int[10]");
for ($i = 0; $i < 10; $i++) { for ($i = 0; $i < 10; $i++) {
$a[$i] = $i; $a[$i] = $i;
} }

View file

@ -12,11 +12,13 @@ if (pack('S', 0xABCD) !== pack('v', 0xABCD)) {
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$x = FFI::new("int"); $ffi = FFI::cdef();
$x = $ffi->new("int");
$x->cdata = 5; $x->cdata = 5;
var_dump($x); var_dump($x);
var_dump(FFI::typeof($x)); var_dump(FFI::typeof($x));
var_dump(FFI::cast("int8_t[4]", $x)); var_dump($ffi->cast("int8_t[4]", $x));
$p = FFI::addr($x); $p = FFI::addr($x);
var_dump($p); var_dump($p);
$p[0] += 2; $p[0] += 2;
@ -28,11 +30,11 @@ var_dump(FFI::string($x, 4));
echo "\n"; echo "\n";
$y = FFI::new("int[2]"); $y = FFI::cdef()->new("int[2]");
$y[0] = 6; $y[0] = 6;
var_dump($y[0]); var_dump($y[0]);
var_dump(FFI::typeof($y[0])); var_dump(FFI::typeof($y[0]));
var_dump(FFI::cast("int8_t[4]", $y[0])); var_dump(FFI::cdef()->cast("int8_t[4]", $y[0]));
$p = FFI::addr($y[0]); $p = FFI::addr($y[0]);
var_dump($p); var_dump($p);
$p[0] += 2; $p[0] += 2;

View file

@ -8,10 +8,10 @@ ffi.enable=1
<?php <?php
function test_new_ownership($str, $transfer) { function test_new_ownership($str, $transfer) {
if ($transfer) { if ($transfer) {
return FFI::new(FFI::type($str)); return FFI::cdef()->new(FFI::cdef()->type($str));
} else { } else {
$type = FFI::type($str); $type = FFI::cdef()->type($str);
return FFI::new($type); return FFI::cdef()->new($type);
} }
} }
var_dump(test_new_ownership("int", 1)); var_dump(test_new_ownership("int", 1));
@ -21,9 +21,9 @@ var_dump(test_new_ownership("int[2]", 0));
function test_type_ownership($str, $transfer) { function test_type_ownership($str, $transfer) {
if ($transfer) { if ($transfer) {
return FFI::typeof(FFI::new($str)); return FFI::typeof(FFI::cdef()->new($str));
} else { } else {
$data = FFI::new($str); $data = FFI::cdef()->new($str);
return FFI::typeof($data); return FFI::typeof($data);
} }
} }
@ -34,10 +34,10 @@ var_dump(test_type_ownership("int[2]", 0));
function test_cast_ownership($str, $transfer) { function test_cast_ownership($str, $transfer) {
if ($transfer) { if ($transfer) {
return FFI::cast(FFI::type($str), FFI::new($str)); return FFI::cdef()->cast(FFI::cdef()->type($str), FFI::cdef()->new($str));
} else { } else {
$type = FFI::type($str); $type = FFI::cdef()->type($str);
return FFI::cast($type, FFI::new($str)); return FFI::cdef()->cast($type, FFI::cdef()->new($str));
} }
} }
var_dump(test_cast_ownership("int", 1)); var_dump(test_cast_ownership("int", 1));
@ -47,9 +47,9 @@ var_dump(test_cast_ownership("int[2]", 0));
function test_array_ownership($str, $transfer) { function test_array_ownership($str, $transfer) {
if ($transfer) { if ($transfer) {
return FFI::arrayType(FFI::type($str), [2]); return FFI::arrayType(FFI::cdef()->type($str), [2]);
} else { } else {
$type = FFI::type($str); $type = FFI::cdef()->type($str);
return FFI::arrayType($type, [2]); return FFI::arrayType($type, [2]);
} }
} }

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$a = FFI::new("uint8_t[8]"); $a = FFI::cdef()->new("uint8_t[8]");
$a[] = 0; $a[] = 0;
?> ?>
--EXPECTF-- --EXPECTF--

View file

@ -6,8 +6,8 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
var_dump(FFI::isNull(FFI::new("int*"))); var_dump(FFI::isNull(FFI::cdef()->new("int*")));
$i = FFI::new("int"); $i = FFI::cdef()->new("int");
var_dump(FFI::isNull(FFI::addr($i))); var_dump(FFI::isNull(FFI::addr($i)));
try { try {
var_dump(FFI::isNull(null)); var_dump(FFI::isNull(null));
@ -15,7 +15,7 @@ try {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }
try { try {
var_dump(FFI::isNull(FFI::new("int[0]"))); var_dump(FFI::isNull(FFI::cdef()->new("int[0]")));
} catch (Throwable $e) { } catch (Throwable $e) {
echo get_class($e) . ": " . $e->getMessage()."\n"; echo get_class($e) . ": " . $e->getMessage()."\n";
} }

View file

@ -51,18 +51,27 @@ var_dump($x->getPointerType()->getFuncParameterCount());
var_dump($x->getPointerType()->getFuncParameterType(0)->getKind() === $x::TYPE_DOUBLE); var_dump($x->getPointerType()->getFuncParameterType(0)->getKind() === $x::TYPE_DOUBLE);
var_dump($x->getPointerType()->getFuncParameterType(1)->getKind() === $x::TYPE_SINT32); var_dump($x->getPointerType()->getFuncParameterType(1)->getKind() === $x::TYPE_SINT32);
?> ?>
--EXPECT-- --EXPECTF--
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
int(1) int(1)
int(1) int(1)
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
bool(true) bool(true)
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
int(5) int(5)
bool(true) bool(true)
int(5) int(5)
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
bool(true) bool(true)
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
bool(false) bool(false)
array(2) { array(2) {
@ -75,6 +84,8 @@ int(0)
int(8) int(8)
bool(true) bool(true)
bool(true) bool(true)
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
bool(true) bool(true)
array(2) { array(2) {
@ -87,6 +98,8 @@ int(0)
int(0) int(0)
bool(true) bool(true)
bool(true) bool(true)
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
bool(true) bool(true)
bool(true) bool(true)
bool(true) bool(true)

View file

@ -6,11 +6,11 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$x = FFI::new("int"); $x = FFI::cdef()->new("int");
$x->cdata = 42; $x->cdata = 42;
var_dump($x); var_dump($x);
$x = FFI::new("int*"); $x = FFI::cdef()->new("int*");
try { try {
$x->cdata = 42; $x->cdata = 42;
var_dump($x); var_dump($x);
@ -18,7 +18,7 @@ try {
echo $e->getMessage() . "\n"; echo $e->getMessage() . "\n";
} }
$x = FFI::new("struct {int cdata;}"); $x = FFI::cdef()->new("struct {int cdata;}");
try { try {
$x->cdata = 42; $x->cdata = 42;
var_dump($x); var_dump($x);

View file

@ -7,7 +7,7 @@ ffi.enable=1
--FILE-- --FILE--
<?php <?php
error_reporting(E_ALL & ~E_DEPRECATED); error_reporting(E_ALL & ~E_DEPRECATED);
$data = FFI::new('int'); $data = FFI::cdef()->new('int');
var_dump(reset($data)); var_dump(reset($data));
var_dump(end($data)); var_dump(end($data));
var_dump(next($data)); var_dump(next($data));

View file

@ -33,7 +33,7 @@ int printf(const char *format, ...);
"); ");
var_dump(FFI::sizeof($x->new("uint8_t"))); var_dump(FFI::sizeof($x->new("uint8_t")));
var_dump(FFI::sizeof(FFI::new("uint8_t"))); var_dump(FFI::sizeof(FFI::cdef()->new("uint8_t")));
?> ?>
--EXPECT-- --EXPECT--
int(4) int(4)

View file

@ -14,7 +14,7 @@ opcache.preload={PWD}/bug78761_preload.php
--FILE-- --FILE--
<?php <?php
try { try {
FFI::cast('char[10]', FFI::new('char[1]')); FFI::cdef()->cast('char[10]', FFI::cdef()->new('char[1]'));
} catch (FFI\Exception $ex) { } catch (FFI\Exception $ex) {
echo $ex->getMessage(), PHP_EOL; echo $ex->getMessage(), PHP_EOL;
} }

View file

@ -5,7 +5,7 @@ ffi
--FILE-- --FILE--
<?php <?php
try { try {
FFI::cast('char[10]', FFI::new('char[1]')); FFI::cdef()->cast('char[10]', FFI::cdef()->new('char[1]'));
} catch (FFI\Exception $ex) { } catch (FFI\Exception $ex) {
echo $ex->getMessage(), PHP_EOL; echo $ex->getMessage(), PHP_EOL;
} }

View file

@ -21,7 +21,7 @@ if (PHP_OS_FAMILY !== 'Windows') {
} }
} }
$array = FFI::new("off_t[3]"); $array = FFI::cdef()->new("off_t[3]");
$ffi->bug79532($array, 3); $ffi->bug79532($array, 3);
var_dump($array); var_dump($array);
?> ?>

View file

@ -6,8 +6,8 @@ ffi
<?php <?php
$ffi = FFI::cdef('typedef int dummy;'); $ffi = FFI::cdef('typedef int dummy;');
var_dump((bool) $ffi); var_dump((bool) $ffi);
var_dump((bool) FFI::type('int')); var_dump((bool) FFI::cdef()->type('int'));
var_dump((bool) FFI::new('int')); var_dump((bool) FFI::cdef()->new('int'));
?> ?>
--EXPECT-- --EXPECT--
bool(true) bool(true)

View file

@ -0,0 +1,61 @@
--TEST--
Test calling the deprecated signature of FFI::new(), FFI::type(), FFI::cast()
--EXTENSIONS--
ffi
--INI--
ffi.enable=1
--FILE--
<?php
$p1 = FFI::new("uint8_t[2]");
set_error_handler(function ($severity, $message, $file, $line) {
throw new Exception($message);
});
try {
FFI::new("uint8_t[2]");
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
set_error_handler(null);
var_dump($p1);
$t1 = FFI::type("uint16_t[2]");
set_error_handler(function ($severity, $message, $file, $line) {
throw new Exception($message);
});
try {
FFI::type("uint16_t[2]");
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
set_error_handler(null);
$p = FFI::cast("uint8_t[2]", $p1);
set_error_handler(function ($severity, $message, $file, $line) {
throw new Exception($message);
});
try {
FFI::cast("uint8_t[2]", $p1);
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECTF--
Deprecated: Calling FFI::new() statically is deprecated in %s on line %d
Calling FFI::new() statically is deprecated
object(FFI\CData:uint8_t[2])#1 (2) {
[0]=>
int(0)
[1]=>
int(0)
}
Deprecated: Calling FFI::type() statically is deprecated in %s on line %d
Calling FFI::type() statically is deprecated
Deprecated: Calling FFI::cast() statically is deprecated in %s on line %d
Calling FFI::cast() statically is deprecated

View file

@ -6,19 +6,19 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$value = FFI::new('char[26]'); $value = FFI::cdef()->new('char[26]');
FFI::memcpy($value, implode('', range('a', 'z')), 26); FFI::memcpy($value, implode('', range('a', 'z')), 26);
$slice = FFI::new('char[4]'); $slice = FFI::cdef()->new('char[4]');
echo 'cast from start' . PHP_EOL; echo 'cast from start' . PHP_EOL;
FFI::memcpy($slice, $value, 4); FFI::memcpy($slice, $value, 4);
var_dump($value + 0, $slice, FFI::cast('char[4]', $value)); var_dump($value + 0, $slice, FFI::cdef()->cast('char[4]', $value));
echo PHP_EOL; echo PHP_EOL;
echo 'cast with offset' . PHP_EOL; echo 'cast with offset' . PHP_EOL;
FFI::memcpy($slice, $value + 4, 4); FFI::memcpy($slice, $value + 4, 4);
var_dump($value + 4, $slice, FFI::cast('char[4]', $value + 4)); var_dump($value + 4, $slice, FFI::cdef()->cast('char[4]', $value + 4));
echo PHP_EOL; echo PHP_EOL;
?> ?>
--EXPECTF-- --EXPECTF--

View file

@ -6,7 +6,7 @@ ffi
ffi.enable=1 ffi.enable=1
--FILE-- --FILE--
<?php <?php
$x = FFI::new('int'); $x = FFI::cdef()->new('int');
array_walk($x, function($x) { echo "test\n"; }); array_walk($x, function($x) { echo "test\n"; });
?> ?>
DONE DONE

View file

@ -5,7 +5,7 @@ ffi
--FILE-- --FILE--
<?php <?php
$x = FFI::new("int[2]"); $x = FFI::cdef()->new("int[2]");
$x[0] = 10; $x[0] = 10;
$x[1] = 25; $x[1] = 25;

View file

@ -4,7 +4,7 @@ Bug #77638 (var_export'ing certain class instances segfaults)
ffi ffi
--FILE-- --FILE--
<?php <?php
var_export(FFI::new('int')); var_export(FFI::cdef()->new('int'));
?> ?>
--EXPECT-- --EXPECT--
\FFI\CData::__set_state(array( \FFI\CData::__set_state(array(