From 75a930980182f6bbbb01cd1bf92c948f45880157 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 5 Feb 2026 15:02:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E6=A0=87?= =?UTF-8?q?=E9=87=8F=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=92=8Cyield?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增AstNodeType::isScalar方法用于检查标量类型 - 在CompilerBase中添加对Expr_Yield和Expr_YieldFrom表达式的错误处理 - 修改变量表达式判断逻辑,排除标量类型的情况 - 添加digit_count示例程序用于数字位数计算性能测试 --- examples/digit_count.php | 37 +++++++++++++++++++++++++++++++++++++ src/Php/AstNodeType.php | 5 +++++ src/Php/CompilerBase.php | 5 ++++- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 examples/digit_count.php diff --git a/examples/digit_count.php b/examples/digit_count.php new file mode 100644 index 00000000..42ce046b --- /dev/null +++ b/examples/digit_count.php @@ -0,0 +1,37 @@ += 1) { + ++$count; + $x /= 10; + } + return $count; +} + +function main() +{ + $b = microtime( true); + $n = 100_0000; + $v = 123456789000; + while($n --) { + $r = digit_count($v); +// $r = strlen(strval($v)); + } + + $e = microtime( true); + echo "sec: " . ($e - $b) . "\n"; + var_dump($r); +} \ No newline at end of file diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index f75c3c9e..f5f4f57e 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -58,4 +58,9 @@ trait AstNodeType { return $expr instanceof Expr\FuncCall; } + + protected function isScalar(NodeAbstract $expr): bool + { + return $expr instanceof Node\Scalar; + } } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 6aeadbd2..3212a6bb 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -414,6 +414,9 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseErrorSuppress($expr); case 'Expr_Exit': return $this->parseExit($expr); + case 'Expr_Yield': + case 'Expr_YieldFrom': + $this->fatalError($expr, 'The `' . $type . '` is not supported'); default: abort($expr); } @@ -1207,7 +1210,7 @@ class CompilerBase extends \PhpAot\Core\Translator $exprCode = $this->convertExprType($expr, $this->getReturnType(), $type); // return 如果使用了 Indirect 语句,可能会导致变量提前析构,出现悬空指针 // 将 Indirect 赋值给临时变量后,使用 Ctor::Copy 解除了 Indirect,保证内存安全 - if (!$this->isVarExpr($v->expr)) { + if (!$this->isVarExpr($v->expr) and !$this->isScalar($v->expr)) { $tmpVar = $this->genTmpVarName(); // 必须提前声明变量,否则在末尾声明并 return 可能会被 gcc 优化掉 $this->addLocalVar($tmpVar, $type);