fix(php): 修复编译器中的变量声明和属性获取问题

- 在循环中为键变量和值变量添加本地变量声明检查
- 确保变量在使用前已正确定义
- 添加对属性获取表达式的处理支持
- 为递增递减操作添加新的测试用例
- 包括64位平台整数溢出处理的测试
- 添加布尔类型递增递减异常处理测试
- 添加引用属性递增递减功能测试
pull/1/head
韩天峰 7 months ago
parent f48b1f4781
commit 166f53f28e
  1. 15
      src/Php/CompilerBase.php
  2. 25
      tests/zend/in-de-crement/decrement_001_64bit.phpt
  3. 28
      tests/zend/in-de-crement/incdec_bool_exception.phpt
  4. 27
      tests/zend/in-de-crement/incdec_ref_property.phpt
  5. 24
      tests/zend/in-de-crement/increment_001_64bit.phpt
  6. 12
      tests/zend/in-de-crement/post_inc_without_use.phpt

@ -2064,7 +2064,10 @@ class CompilerBase extends \PhpAot\Core\Translator
$code = 'for (auto iter = ' . $iteratorVar . '.begin(); iter != ' . $iteratorVar . '.end(); ++iter) {' . PHP_EOL;
$this->indentLevel++;
if ($node->keyVar) {
$code .= self::TYPE_VAR . ' ' . $this->getIndent() . ' ' . $keyVar . ' = iter.key();' . PHP_EOL;
if (!$this->hasVar($keyVar)) {
$this->addLocalVar($keyVar, self::TYPE_VAR);
}
$code .= $this->getIndent() . ' ' . $keyVar . ' = iter.key();' . PHP_EOL;
}
if ($node->valueVar->getType() == self::EXPR_ARRAY_DIM_FETCH) {
@ -2076,7 +2079,10 @@ class CompilerBase extends \PhpAot\Core\Translator
$code .= $this->getIndent() . "$array.offsetSet($dim, iter.value());";
} else {
$valueVar = $this->parseIdentifier($node->valueVar);
$code .= self::TYPE_VAR . ' ' . $this->getIndent() . ' ' . $valueVar . ' = iter.value();' . PHP_EOL;
if (!$this->hasVar($valueVar)) {
$this->addLocalVar($valueVar, self::TYPE_VAR);
}
$code .= $this->getIndent() . ' ' . $valueVar . ' = iter.value();' . PHP_EOL;
}
$body = $this->parseStmts($node->stmts);
@ -2356,6 +2362,11 @@ class CompilerBase extends \PhpAot\Core\Translator
return $var . ' = &' . $this->parseIdentifier($expr->expr);
} elseif ($expr->expr->getType() === self::EXPR_ARRAY_DIM_FETCH) {
return $var . ' = ' . $this->parseIdentifier($expr->expr);
} elseif ($this->isPropertyFetch($expr->expr)) {
$var = $this->parseIdentifier($expr->var);
$object = $this->convertToObject($expr->expr->var);
$prop = $this->identifierToStr($expr->expr->name);
return $var . ' = ' . $object . '.getPropertyReference(' . $prop . ')';
}
}
abort($expr);

@ -0,0 +1,25 @@
--TEST--
Decrementing min int values 64bit
--SKIPIF--
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
--INI--
precision=14
--FILE--
<?php
$values = [
-PHP_INT_MAX-1.0,
(string)(-PHP_INT_MAX-1.0),
];
foreach ($values as $var) {
$var--;
var_dump($var);
}
echo "Done\n";
?>
--EXPECT--
float(-9.223372036854776E+18)
float(-9.223372036854776E+18)
Done

@ -0,0 +1,28 @@
--TEST--
Inc/dec on bool: warning converted to exception
--FILE--
<?php
$values = [false, true];
foreach ($values as $value) {
try {
$value++;
} catch (\Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
try {
$value--;
} catch (\Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
}
?>
--EXPECT--
Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1
Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1
Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1
Warning: Increment on type bool has no effect, this will change in the next major version of PHP in Unknown(0) : eval() on line 1

@ -0,0 +1,27 @@
--TEST--
Incrementing and decrementing a referenced property
--FILE--
<?php
$obj = new stdClass;
$obj->prop = 1;
$ref =& $obj->prop;
var_dump(++$obj->prop);
var_dump($obj->prop);
var_dump($obj->prop++);
var_dump($obj->prop);
var_dump(--$obj->prop);
var_dump($obj->prop);
var_dump($obj->prop--);
var_dump($obj->prop);
?>
--EXPECT--
int(2)
int(2)
int(2)
int(3)
int(2)
int(2)
int(2)
int(1)

@ -0,0 +1,24 @@
--TEST--
Incrementing max int values 64bit
--SKIPIF--
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
--INI--
precision=14
--FILE--
<?php
$values = [
PHP_INT_MAX,
(string)PHP_INT_MAX
];
foreach ($values as $var) {
$var++;
var_dump($var);
}
echo "Done\n";
?>
--EXPECT--
float(9.223372036854776E+18)
float(9.223372036854776E+18)
Done

@ -0,0 +1,12 @@
--TEST--
POST_INC without use during DFA optimization
--FILE--
<?php
function main() {
$n = 10;
for ($i = 0; $i < $n; !$i++) {}
}
?>
--EXPECT--
Loading…
Cancel
Save