修复复合赋值运算符(如 +=)在数组元素上使用时返回值错误的问题。 之前代码使用了存储变量而非读取变量进行运算,并且未正确返回运算结果。 现在通过使用读取变量参与计算并返回临时变量值来修复此问题, 同时添加了 FFI 和数组相关的测试用例。pull/14/head
parent
4ceb938009
commit
6afb8e3689
9 changed files with 257 additions and 5 deletions
@ -0,0 +1,31 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI addr cast typeof and sizeof |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$value = FFI::new("int"); |
||||||
|
$value->cdata = 123; |
||||||
|
|
||||||
|
$addr = FFI::addr($value); |
||||||
|
$ptr = FFI::cast("int*", $addr); |
||||||
|
$type = FFI::typeof($value); |
||||||
|
|
||||||
|
var_dump($addr instanceof FFI\CData); |
||||||
|
var_dump($ptr instanceof FFI\CData); |
||||||
|
var_dump($type instanceof FFI\CType); |
||||||
|
var_dump(FFI::sizeof($type)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
int(4) |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI multidimensional array assignment keeps CData containers |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$ffi = FFI::cdef(); |
||||||
|
|
||||||
|
$matrix = $ffi->new("int[2][2]"); |
||||||
|
$row = $ffi->new("int[2]"); |
||||||
|
$row[0] = 11; |
||||||
|
$row[1] = 22; |
||||||
|
$matrix[1] = $row; |
||||||
|
|
||||||
|
var_dump($matrix instanceof FFI\CData); |
||||||
|
var_dump($row instanceof FFI\CData); |
||||||
|
var_dump(FFI::sizeof($matrix)); |
||||||
|
var_dump(FFI::sizeof($row)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
int(16) |
||||||
|
int(8) |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI array element compound assignment reads scalar value |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$array = FFI::new("int[3]"); |
||||||
|
$array[0] = 10; |
||||||
|
$array[1] = 20; |
||||||
|
$array[2] = 30; |
||||||
|
|
||||||
|
$result = ($array[0] += 5); |
||||||
|
var_dump($array[0]); |
||||||
|
var_dump($result); |
||||||
|
|
||||||
|
$array[1] *= 2; |
||||||
|
var_dump($array[1]); |
||||||
|
|
||||||
|
$array[2] -= $array[0]; |
||||||
|
var_dump($array[2]); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(15) |
||||||
|
int(15) |
||||||
|
int(40) |
||||||
|
int(15) |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI array element scalar read matches PHP |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$array = FFI::new("int[3]"); |
||||||
|
$array[0] = 10; |
||||||
|
$array[1] = 20; |
||||||
|
$array[2] = 30; |
||||||
|
|
||||||
|
var_dump($array[0]); |
||||||
|
var_dump($array[0] + $array[1]); |
||||||
|
var_dump($array[0] === 10); |
||||||
|
var_dump($array[0] == 10); |
||||||
|
var_dump(is_int($array[0])); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(10) |
||||||
|
int(30) |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI basic CData and libc call |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--SKIPIF-- |
||||||
|
<?php |
||||||
|
try { |
||||||
|
FFI::cdef("int abs(int);", "libc.so.6"); |
||||||
|
} catch (Throwable $e) { |
||||||
|
die("skip FFI::cdef is not available: " . $e->getMessage()); |
||||||
|
} |
||||||
|
?> |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$array = FFI::new("int[3]"); |
||||||
|
$array[0] = 10; |
||||||
|
$array[1] = 20; |
||||||
|
$array[2] = 30; |
||||||
|
var_dump($array instanceof FFI\CData); |
||||||
|
|
||||||
|
$libc = FFI::cdef("int abs(int);", "libc.so.6"); |
||||||
|
var_dump($libc->abs(-42)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
int(42) |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI cdef declarations create structs enums and functions |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--SKIPIF-- |
||||||
|
<?php |
||||||
|
try { |
||||||
|
FFI::cdef("int abs(int);", "libc.so.6"); |
||||||
|
} catch (Throwable $e) { |
||||||
|
die("skip FFI::cdef is not available: " . $e->getMessage()); |
||||||
|
} |
||||||
|
?> |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$ffi = FFI::cdef(<<<'CDEF' |
||||||
|
typedef struct point { |
||||||
|
int x; |
||||||
|
int y; |
||||||
|
} point_t; |
||||||
|
|
||||||
|
enum color { |
||||||
|
COLOR_RED = 1, |
||||||
|
COLOR_GREEN = 2 |
||||||
|
}; |
||||||
|
|
||||||
|
int abs(int); |
||||||
|
CDEF |
||||||
|
, "libc.so.6"); |
||||||
|
|
||||||
|
$point = FFI::new("struct point { int x; int y; }"); |
||||||
|
$color = FFI::new("enum color { COLOR_RED = 1, COLOR_GREEN = 2 }"); |
||||||
|
|
||||||
|
var_dump($point instanceof FFI\CData); |
||||||
|
var_dump($color instanceof FFI\CData); |
||||||
|
var_dump(FFI::sizeof($point)); |
||||||
|
var_dump($ffi->abs(-7)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
int(8) |
||||||
|
int(7) |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
--TEST-- |
||||||
|
FFI struct field write and address |
||||||
|
--EXTENSIONS-- |
||||||
|
ffi |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--INI-- |
||||||
|
ffi.enable=1 |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$node = FFI::new(<<<'CDEF' |
||||||
|
struct node { |
||||||
|
int id; |
||||||
|
int value; |
||||||
|
} |
||||||
|
CDEF); |
||||||
|
$node->id = 123; |
||||||
|
$node->value = 456; |
||||||
|
$addr = FFI::addr($node); |
||||||
|
|
||||||
|
var_dump($node instanceof FFI\CData); |
||||||
|
var_dump($addr instanceof FFI\CData); |
||||||
|
var_dump(FFI::sizeof($node)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECTF-- |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
int(%d) |
||||||
Loading…
Reference in new issue