From 8ec0723ed5ab1bbf04d44991265cd1098e5697ca Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 10 Feb 2026 21:26:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=8C=BF?= =?UTF-8?q?=E5=90=8D=E7=B1=BB=E6=94=AF=E6=8C=81=E5=92=8C=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 ANON_CLASS 常量用于生成匿名类名称 - 添加 constData 数组用于存储常量数据 - 实现 genAnonClassName 方法生成唯一匿名类名 - 修复 Stmt_Class 处理中的 break 语句缺失问题 - 扩展 parsePostOp 方法支持数组维度获取并检查未定义变量 - 实现 packData 和 addConstData 方法处理字节数据打包 - 在 parseNew 方法中实现对匿名类的完整支持 - 在生成的 C++ 代码中添加常量数据段输出 --- src/Php/CompilerBase.php | 52 ++++++++++++++++++++++++++++++++++++---- src/Php/Translator.php | 8 ++++++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index f9f05a1d..d49f1280 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -62,6 +62,7 @@ class CompilerBase extends \PhpAot\Core\Translator public const string NAMESPACE_SEPARATOR = '__'; public const string PREFIX = 'php_'; + public const string ANON_CLASS = '_anon_class_'; public const string OP_ISSET = 'isset'; public const string OP_EMPTY = 'empty'; public const string OP_NOP = "if (0) {}\n"; @@ -105,6 +106,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $functionDeclInFile = []; protected array $functionCallInFile = []; protected array $redoAfterDeclare = []; + protected array $constData = []; protected int $optimizeLevel = 0; protected string $buildMode = 'bin'; protected string $cxxflags = ''; @@ -481,6 +483,11 @@ class CompilerBase extends \PhpAot\Core\Translator return 'tmp_var_' . $this->tmpVarIndex++; } + public function genAnonClassName(): string + { + return self::ANON_CLASS . $this->tmpVarIndex++; + } + public function writeFile(string $file, string $content): void { $dir = dirname($file); @@ -964,7 +971,7 @@ class CompilerBase extends \PhpAot\Core\Translator break; case 'Stmt_Class': $this->fatalError($v, 'Cannot declare class in function'); - // no break + break; default: abort($v); } @@ -2001,8 +2008,12 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePostOp($expr, string $op): string { - if ($this->isVarExpr($expr->var) or $this->isPropertyFetch($expr->var)) { - return $this->parseIdentifier($expr->var) . str_repeat($op, 2); + if ($this->isVarExpr($expr->var) or $this->isPropertyFetch($expr->var) or $this->isArrayDimFetch($expr->var)) { + $var = $this->parseIdentifier($expr->var); + if ($this->isVarExpr($expr->var) and !$this->hasVar($var)) { + $this->errorUndefinedVariable($expr->var); + } + return $var . str_repeat($op, 2); } if ($this->isStaticPropertyFetch($expr->var)) { $native = $this->parseNativeStaticPropertyFetch($expr->var); @@ -2334,9 +2345,42 @@ class CompilerBase extends \PhpAot\Core\Translator return '!(' . $this->parseBinaryOpIdentical($expr) . ')'; } + protected function packData(string $bytes): string + { + $out = ''; + for ($i = 0; $i < strlen($bytes); $i++) { + $out .= ord($bytes[$i]) . ', '; + if ($i % 32 == 0) { + $out .= "\n\t"; + } + } + return $out; + } + + protected function addConstData(string $name, string $bytes): void + { + $this->constData[$name] = $this->packData($bytes); + } + protected function parseNew(Node\Expr\New_ $expr): string { - $className = $this->parseIdentifier($expr->class); + // 匿名类 + if ($expr->class instanceof Node\Stmt\Class_) { + if ($expr->class->name === null) { + $classDef = $expr->class; + $className = $this->genAnonClassName(); + $classDef->name = new Node\Identifier($className); + $this->beforeStmtLines[] = 'static THREAD_LOCAL bool ' . $className . '_defined = false;'; + $classCode = $this->genEmbeddedCode($classDef); + $this->addConstData($className . '_code', $classCode); + $this->beforeStmtLines[] = 'if (!' . $className . '_defined) {' + . $className . '_defined = true; php::eval((const char *)' . $className . '_code);}'; + } else { + $this->fatalError($expr, 'must be anonymous class'); + } + } else { + $className = $this->parseIdentifier($expr->class); + } $className = $this->getNamespacedClassName($className); $args = $expr->args; $cePtr = $this->getClassEntryPtr($className); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index cee79e9a..9ebba593 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -513,7 +513,13 @@ class Translator extends Preprocessor $cppCode .= $this->genFunctionWrapper($functionDef); } - return $this->genIncludeHeaderFiles() . $cppCode; + $constDataCode = ''; + foreach ($this->constData as $name => $data) { + $constDataCode .= 'static const unsigned char ' . $name . '[] = {' . $data . '};' . PHP_EOL; + } + $constDataCode .= PHP_EOL; + + return $this->genIncludeHeaderFiles() . $constDataCode . $cppCode; } protected function genClassCeList(): void