diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index 992a688b..23c8de34 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -386,18 +386,19 @@ trait AssignOpTrait $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, $rightType); $dim = $this->parseIdentifier($node->var->dim); + $readVar = $this->parseArrayDimFetch($node->var, false); $binaryOp = $this->removeAssignOp($op); if ($binaryOp === '.') { $this->context->beforeStmtLines[] = "{$tmpVar} = php::concat(" . - $this->convertVarType($tmpVar, $var) . ', ' . + $this->convertVarType($tmpVar, $readVar) . ', ' . $this->convertExprType($expr, $type, $rightType) . ');'; } elseif ($type === self::TYPE_BIGINT || $type === self::TYPE_DECIMAL || $type === self::TYPE_BIGFLOAT) { - $bigAssign = $this->parseBigAssignOpExpr($var, $type, $expr, $rightType, $binaryOp, $node->var, $node->expr); + $bigAssign = $this->parseBigAssignOpExpr($readVar, $type, $expr, $rightType, $binaryOp, $node->var, $node->expr); $this->context->beforeStmtLines[] = "{$tmpVar} = {$bigAssign};"; } else { $this->context->beforeStmtLines[] = "{$tmpVar} = " . - $this->convertVarType($tmpVar, $var) . ' ' . + $this->convertVarType($tmpVar, $readVar) . ' ' . $binaryOp . ' ' . $this->convertExprType($expr, $type, $rightType) . ';'; } @@ -405,7 +406,7 @@ trait AssignOpTrait if ($this->isVarExpr($node->var->var) && $node->var->var->name === 'GLOBALS') { return $var . ' = ' . $tmpVar; } - return $this->parseArrayDimStore($node->var->var, $dim, $tmpVar); + return '(' . $this->parseArrayDimStore($node->var->var, $dim, $tmpVar) . ', ' . $tmpVar . ')'; } if ($this->isPropertyFetch($node->var) and !$this->isNativePropertyAccess($node->var)) { diff --git a/tests/aot/array/array_assignment_operators.phpt b/tests/aot/array/array_assignment_operators.phpt index 5d245dde..1461d64f 100644 --- a/tests/aot/array/array_assignment_operators.phpt +++ b/tests/aot/array/array_assignment_operators.phpt @@ -95,6 +95,11 @@ $seqArray['counter'] -= 3; $seqArray['counter'] /= 7; var_dump($seqArray['counter']); // 1 (7*2-3=7, then 7/7=1) +$exprResult = ['value' => 10]; +$compoundResult = ($exprResult['value'] += 5); +var_dump($exprResult['value']); +var_dump($compoundResult); + echo "All array assignment tests passed!\n"; ?> --EXPECT-- @@ -121,4 +126,6 @@ string(33) "nested array assignment operators" int(150) int(15) int(1) -All array assignment tests passed! \ No newline at end of file +int(15) +int(15) +All array assignment tests passed! diff --git a/tests/aot/ffi/addr-cast-sizeof.phpt b/tests/aot/ffi/addr-cast-sizeof.phpt new file mode 100644 index 00000000..bb17e0bd --- /dev/null +++ b/tests/aot/ffi/addr-cast-sizeof.phpt @@ -0,0 +1,31 @@ +--TEST-- +FFI addr cast typeof and sizeof +--EXTENSIONS-- +ffi +--ENV-- +USE_ZEND_ALLOC=0 +--INI-- +ffi.enable=1 +--FILE-- +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) diff --git a/tests/aot/ffi/array-assignment.phpt b/tests/aot/ffi/array-assignment.phpt new file mode 100644 index 00000000..7ae29fb5 --- /dev/null +++ b/tests/aot/ffi/array-assignment.phpt @@ -0,0 +1,32 @@ +--TEST-- +FFI multidimensional array assignment keeps CData containers +--EXTENSIONS-- +ffi +--ENV-- +USE_ZEND_ALLOC=0 +--INI-- +ffi.enable=1 +--FILE-- +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) diff --git a/tests/aot/ffi/array-compound-assignment.phpt b/tests/aot/ffi/array-compound-assignment.phpt new file mode 100644 index 00000000..1777b932 --- /dev/null +++ b/tests/aot/ffi/array-compound-assignment.phpt @@ -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-- + +--EXPECT-- +int(15) +int(15) +int(40) +int(15) diff --git a/tests/aot/ffi/array-scalar-read.phpt b/tests/aot/ffi/array-scalar-read.phpt new file mode 100644 index 00000000..19f1b4cd --- /dev/null +++ b/tests/aot/ffi/array-scalar-read.phpt @@ -0,0 +1,31 @@ +--TEST-- +FFI array element scalar read matches PHP +--EXTENSIONS-- +ffi +--ENV-- +USE_ZEND_ALLOC=0 +--INI-- +ffi.enable=1 +--FILE-- + +--EXPECT-- +int(10) +int(30) +bool(true) +bool(true) +bool(true) diff --git a/tests/aot/ffi/basic.phpt b/tests/aot/ffi/basic.phpt new file mode 100644 index 00000000..5313d6c7 --- /dev/null +++ b/tests/aot/ffi/basic.phpt @@ -0,0 +1,34 @@ +--TEST-- +FFI basic CData and libc call +--EXTENSIONS-- +ffi +--ENV-- +USE_ZEND_ALLOC=0 +--INI-- +ffi.enable=1 +--SKIPIF-- +getMessage()); +} +?> +--FILE-- +abs(-42)); +} +?> +--EXPECT-- +bool(true) +int(42) diff --git a/tests/aot/ffi/cdef-declarations.phpt b/tests/aot/ffi/cdef-declarations.phpt new file mode 100644 index 00000000..0ea3e614 --- /dev/null +++ b/tests/aot/ffi/cdef-declarations.phpt @@ -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-- +getMessage()); +} +?> +--FILE-- +abs(-7)); +} +?> +--EXPECT-- +bool(true) +bool(true) +int(8) +int(7) diff --git a/tests/aot/ffi/struct-fields.phpt b/tests/aot/ffi/struct-fields.phpt new file mode 100644 index 00000000..76f28f7d --- /dev/null +++ b/tests/aot/ffi/struct-fields.phpt @@ -0,0 +1,32 @@ +--TEST-- +FFI struct field write and address +--EXTENSIONS-- +ffi +--ENV-- +USE_ZEND_ALLOC=0 +--INI-- +ffi.enable=1 +--FILE-- +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)