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