From 5fd921550940f580bd01b1235b5ddd55a3a02804 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 12 Jan 2026 19:05:25 +0800 Subject: [PATCH] =?UTF-8?q?refactor(Php):=20=E9=87=8D=E6=9E=84=E7=B1=BB?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E5=92=8C=E7=BC=96=E8=AF=91=E5=99=A8=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 ClassDef 中 methods、properties 和 constants 的类型为关联数组 - 在 CompilerBase 中添加 TYPE_VOID 常量并修改函数名获取逻辑 - 将 escapeClass 方法改为小写转换 - 使用 climate 库替换日志输出方法 - 更新 MethodDef 构造函数以支持返回类型 - 重构 Translator 中的类包装器生成逻辑 - 实现原生方法包装器和类包装器功能 - 修改常量和属性存储方式为键值对形式 - 添加方法包装器以支持返回类型处理 --- src/Php/ClassDef.php | 6 ++-- src/Php/CompilerBase.php | 24 ++++++++----- src/Php/MethodDef.php | 7 ++-- src/Php/Translator.php | 73 +++++++++++++++++++++++++++++----------- 4 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/Php/ClassDef.php b/src/Php/ClassDef.php index dacb4203..ccd37f95 100644 --- a/src/Php/ClassDef.php +++ b/src/Php/ClassDef.php @@ -6,15 +6,15 @@ class ClassDef { public string $name; /** - * @var array< MethodDef> + * @var array */ public array $methods = []; /** - * @var array + * @var array */ public array $properties = []; /** - * @var array + * @var array */ public array $constants = []; public string $namespace = ''; diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index af399649..24a7bcd3 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -31,6 +31,7 @@ class CompilerBase extends \PhpAot\Core\Translator public const string TYPE_ARRAY = 'php::Array'; public const string TYPE_STR = 'php::Str'; public const string TYPE_REF = 'php::Var'; + public const string TYPE_VOID = 'void'; public const string VALUE_NAN = 'std::numeric_limits::quiet_NaN()'; public const string VALUE_INF = 'std::numeric_limits::infinity()'; @@ -215,14 +216,19 @@ class CompilerBase extends \PhpAot\Core\Translator $this->namespace = ''; } - protected function getFunctionName(Node $v): string + protected function getFunctionName(FunctionLike $v): string { - $names[] = $this->escapeFunction($this->parseIdentifier($v->name)); - if ($this->namespace) { - $names[] = $this->escapeNamespace($this->namespace); + return $this->getNativeFunctionName($this->parseIdentifier($v->name), $this->namespace, $this->class); + } + + protected function getNativeFunctionName(string $fn, string $ns = '', string $class = ''): string + { + $names[] = $this->escapeFunction($fn); + if ($ns) { + $names[] = $this->escapeNamespace($ns); } - if ($this->class) { - $names[] = $this->escapeClass($this->class); + if ($class) { + $names[] = $this->escapeClass($class); } return implode(self::NAMESPACE_SEPARATOR, array_reverse($names)); } @@ -1785,7 +1791,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function escapeClass(string $class): string { - return $class; + return strtolower($class); } protected function unescapeVarName(string $name): string @@ -1950,8 +1956,8 @@ class CompilerBase extends \PhpAot\Core\Translator protected function formatCppCode(string $file): void { $cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file; - $this->writeLog('formatting ' . $file . '...'); - $this->writeLog($cmd); + $this->climate->info('formatting ' . $file ); + $this->climate->comment($cmd); shell_exec($cmd); } diff --git a/src/Php/MethodDef.php b/src/Php/MethodDef.php index 38b0ed0c..da8ea4ac 100644 --- a/src/Php/MethodDef.php +++ b/src/Php/MethodDef.php @@ -4,13 +4,14 @@ namespace PhpAot\Php; class MethodDef { - public string $name; - public string $flags; + public int $flags; + public string $returnType; - public function __construct(string $name, string $flags) + public function __construct(string $name, int $flags, string $returnType) { $this->name = $name; $this->flags = $flags; + $this->returnType = $returnType; } } \ No newline at end of file diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 969df148..64f95697 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -165,22 +165,9 @@ class Translator extends Preprocessor } foreach ($this->classesDefineInFile as $classDef) { - $name = $classDef->getNamespacedName(); - - if ($classDef->extends) { - $parentName = 'zend_class_entry *parent_ce'; - $param = 'parent_ce'; - } else { - $parentName = ''; - $param = ''; - } - $cppCode .= 'zend_class_entry *' . $this->getRegisterClassFunction($name) . '(' . $parentName . ') {' . PHP_EOL; - $cppCode .= $this->getIndent() . 'return ' . $this->getRegisterClassFunction($name) . '(' . $param . ');' . PHP_EOL; - $cppCode .= '}' . PHP_EOL . PHP_EOL; + $cppCode .= $this->genClassWrapper($classDef); } - $cppCode .= PHP_EOL; - // include + extern global vars + function impl return $this->genIncludeHeaderFiles() . $cppCode; } @@ -362,6 +349,11 @@ class Translator extends Preprocessor return strtolower($this->parseIdentifier($v->name)); } + protected function getNativeMethodName(ClassDef $classDef, MethodDef $methodDef): string + { + return $this->getNativeFunctionName($methodDef->name, $classDef->namespace, $classDef->name); + } + protected function parseNamespace(Node\Stmt\Namespace_ $node): string { $ns = $this->parseIdentifier($node->name); @@ -450,7 +442,7 @@ class Translator extends Preprocessor abort($v); } } - $code = $this->genZendClass($methodCodes); + $code = $this->genNativeMethod($methodCodes); $this->class = ''; return $code; } @@ -466,7 +458,7 @@ class Translator extends Preprocessor } } - protected function genZendClass($methodCodes): string + protected function genNativeMethod($methodCodes): string { $code = ''; $classDef = $this->classDef; @@ -476,6 +468,48 @@ class Translator extends Preprocessor return $code; } + protected function genMethodWrapper(ClassDef $classDef, MethodDef $methodDef): string + { + $name = $classDef->getNamespacedName(); + $cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL; + $cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL; + $fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef); + + if ($methodDef->returnType !== self::TYPE_VOID) { + $cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(this_);' . PHP_EOL; + $cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL; + } else { + $cppCode .= $this->getIndent() . $fn . '(this_);' . PHP_EOL; + } + $cppCode .= '}' . PHP_EOL . PHP_EOL; + + return $cppCode; + } + + + protected function genClassWrapper(ClassDef $classDef): string + { + $cppCode = ''; + $name = $classDef->getNamespacedName(); + + if ($classDef->extends) { + $parentName = 'zend_class_entry *parent_ce'; + $param = 'parent_ce'; + } else { + $parentName = ''; + $param = ''; + } + $cppCode .= 'zend_class_entry *' . $this->getRegisterClassFunction($name) . '(' . $parentName . ') {' . PHP_EOL; + $cppCode .= $this->getIndent() . 'return ' . $this->getRegisterClassFunction($name) . '(' . $param . ');' . PHP_EOL; + $cppCode .= '}' . PHP_EOL . PHP_EOL; + + $methods = $classDef->methods; + foreach ($methods as $methodDef) { + $cppCode .= $this->genMethodWrapper($classDef, $methodDef); + } + return $cppCode; + } + private function genClassNative(): string { $code = 'class ' . $this->class . ' { '; @@ -624,7 +658,7 @@ class Translator extends Preprocessor $type = $v->type ? $this->getTypeFromZendType($this->parseIdentifier($v->type)) : self::TYPE_VAR; foreach ($v->consts as $const) { $constInfo = new ConstantDef($this->parseIdentifier($const->name), $flags, $type, $this->parseIdentifier($const->value)); - $this->classDef->constants[] = $constInfo; + $this->classDef->constants[$constInfo->name] = $constInfo; } } @@ -638,7 +672,7 @@ class Translator extends Preprocessor if ($prop->default) { $propDef->default = $this->parseIdentifier($prop->default); } - $this->classDef->properties[] = $propDef; + $this->classDef->properties[$propDef->name] = $propDef; } } @@ -646,7 +680,8 @@ class Translator extends Preprocessor { $name = $this->getMethodName($v); $flags = $v->flags; - $methodDef = new MethodDef($name, $flags); + $returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID; + $methodDef = new MethodDef($name, $flags, $returnType); $this->classDef->methods[$name] = $methodDef; $methodCodes[$name] = $this->parseFunction($v); }