From cba9990e8021b743fbc593a974e21c26acc17ead Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 18 Jun 2026 15:27:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor(parser):=20=E9=87=8D=E6=9E=84=E9=9B=B6?= =?UTF-8?q?=E5=80=BC=E5=AD=97=E9=9D=A2=E9=87=8F=E6=A3=80=E6=B5=8B=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 isZeroLiteral 方法从 BinaryOpTrait 移动到 CompilerBase 类中 - 为 isZeroLiteral 方法添加详细的文档注释说明其用途 - 添加 targetPlatform 配置选项支持交叉编译目标平台 - 修复对象属性测试用例中的数组索引访问功能 - 在 array_sum 和 array_product 测试中添加错误报告控制 --- src/Php/CompilerBase.php | 38 +++++++++++++++++++++++++++--- src/Php/Parser/BinaryOpTrait.php | 18 -------------- tests/aot/object_property/007.phpt | 24 +++++++++++++++++++ tests/std/array/007.phpt | 1 + 4 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 tests/aot/object_property/007.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 13be2ff5..d4bd369b 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -242,6 +242,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected string $cxxFlags = ''; protected string $cxxStd = 'c++17'; protected string $march = ''; // --march: target CPU instruction set (e.g. native, x86-64-v3) + protected string $targetPlatform = ''; // --target-platform: cross-compilation target triple (e.g. aarch64-linux-gnu) protected string $ldflags = ''; protected array $linkLibs = []; // --link-lib / -l: user-specified libraries to link protected array $linkPaths = []; // --link-path / -L: user-specified library search paths @@ -1207,14 +1208,42 @@ class CompilerBase extends \PhpAot\Core\Translator $key = $this->parseIdentifier($expr); if (str_starts_with($key, self::LITERAL_STRINGS)) { $key = "{$key}.str()"; - } elseif ($key === '0L' || $key === '0LL') { - // 0 在 C++ 中是一个特殊的值,存在二义性,既是空指针,也是整数,这会导致产生 ambiguous 错误 - // 必须转为 php::zero 常量,保证作为 key 时正确匹配到 IntKeyMap + } elseif ($this->isZeroLiteral($expr)) { $key = self::VALUE_ZERO; } return $key; } + /** + * Check if a node is a literal zero value. + * + * Detects compile-time zero for two purposes: + * - Division-by-zero guard (any zero form: int, float, negated, numeric string) + * - C++ null pointer ambiguity guard: Scalar_Int(0) → 0L → nullptr → segfault + * when passed to functions with zend_string* overloads (setProperty, getProperty, etc.) + */ + protected function isZeroLiteral(NodeAbstract $expr): bool + { + if ($expr instanceof Node\Scalar\Int_) { + $result = $expr->value === 0; + return $result; + } + if ($expr instanceof Node\Scalar\Float_) { + $result = $expr->value == 0.0; + return $result; + } + if ($expr instanceof Expr\UnaryMinus || $expr instanceof Expr\UnaryPlus) { + $result = $this->isZeroLiteral($expr->expr); + return $result; + } + if ($expr instanceof Node\Scalar\String_) { + $value = trim($expr->value); + $result = $value !== '' && is_numeric($value) && (float) $value == 0.0; + return $result; + } + return false; + } + protected function parseIdentifier(NodeAbstract $expr): string { $type = $expr->getType(); @@ -4655,6 +4684,9 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isNameExpr($node) or $this->isIdExpr($node)) { return $literal ? $this->getLiteralString($id) : $this->genCharPtr($id, true); } + if ($this->isZeroLiteral($node)) { + return self::VALUE_ZERO; + } return $id; } diff --git a/src/Php/Parser/BinaryOpTrait.php b/src/Php/Parser/BinaryOpTrait.php index 3a776444..bb9fec06 100644 --- a/src/Php/Parser/BinaryOpTrait.php +++ b/src/Php/Parser/BinaryOpTrait.php @@ -362,24 +362,6 @@ trait BinaryOpTrait } } - protected function isZeroLiteral(NodeAbstract $expr): bool - { - if ($expr instanceof Node\Scalar\Int_) { - return $expr->value === 0; - } - if ($expr instanceof Node\Scalar\Float_) { - return $expr->value == 0.0; - } - if ($expr instanceof Expr\UnaryMinus || $expr instanceof Expr\UnaryPlus) { - return $this->isZeroLiteral($expr->expr); - } - if ($expr instanceof Node\Scalar\String_) { - $value = trim($expr->value); - return $value !== '' && is_numeric($value) && (float) $value == 0.0; - } - return false; - } - protected function parseBinaryOpMinus(Expr\BinaryOp\Minus $expr): string { return $this->parseBinaryOp($expr->left, $expr->right, '-'); diff --git a/tests/aot/object_property/007.phpt b/tests/aot/object_property/007.phpt new file mode 100644 index 00000000..3aab3db5 --- /dev/null +++ b/tests/aot/object_property/007.phpt @@ -0,0 +1,24 @@ +--TEST-- +default array property +--FILE-- +{0} = $year; + $o->{1} = $first; + $o->{2} = $last; + var_dump($o); +} +?> +--EXPECTF-- +object(stdClass)#%d (3) { + ["0"]=> + int(1995) + ["1"]=> + string(3) "php" + ["2"]=> + string(4) ".net" +} \ No newline at end of file diff --git a/tests/std/array/007.phpt b/tests/std/array/007.phpt index e27e8838..d2ef083d 100644 --- a/tests/std/array/007.phpt +++ b/tests/std/array/007.phpt @@ -3,6 +3,7 @@ array_sum / array_product: type handling --FILE--