feat(php): 添加标量类型检查和yield表达式支持

- 新增AstNodeType::isScalar方法用于检查标量类型
- 在CompilerBase中添加对Expr_Yield和Expr_YieldFrom表达式的错误处理
- 修改变量表达式判断逻辑,排除标量类型的情况
- 添加digit_count示例程序用于数字位数计算性能测试
pull/1/head
韩天峰 7 months ago
parent d81c4cda62
commit 75a9309801
  1. 37
      examples/digit_count.php
  2. 5
      src/Php/AstNodeType.php
  3. 5
      src/Php/CompilerBase.php

@ -0,0 +1,37 @@
<?php
function digit_count(int $x)
{
if ($x == 0) {
return 1;
}
if ($x == PHP_INT_MAX) {
return 20;
}
$count = 0;
if ($x < 0) {
++$count;
$x = -$x;
}
while ($x >= 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);
}

@ -58,4 +58,9 @@ trait AstNodeType
{
return $expr instanceof Expr\FuncCall;
}
protected function isScalar(NodeAbstract $expr): bool
{
return $expr instanceof Node\Scalar;
}
}

@ -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);

Loading…
Cancel
Save