From 0e4a3325197fbebdec2661f3ac43b1adcb0a7429 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 29 Jan 2026 20:40:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E6=8C=87=E9=92=88=E6=98=A0=E5=B0=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 FUNC_MAP 常量用于存储函数映射 - 添加 funcIndex 和 funcMap 属性用于函数索引管理 - 实现 getFuncPtr 方法获取函数指针 - 修改函数调用逻辑使用新的函数指针机制 - 在扩展模板中添加函数映射数组声明 - 添加 php_get_func 外部函数声明和实现 - 更新翻译器生成相应的外部函数声明 --- src/Php/CompilerBase.php | 22 +++++++++++++++++----- src/Php/Translator.php | 4 ++++ src/template/extension.cc.php | 10 ++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 71be343b..e0708322 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -54,6 +54,7 @@ class CompilerBase extends \PhpAot\Core\Translator public const string LITERAL_STRINGS = '_literal_strings'; public const string CLASS_ENTRY_MAP = 'class_entry_map'; + public const string FUNC_MAP = 'func_map'; public const string EXPR_VARIABLE = 'Expr_Variable'; @@ -85,6 +86,8 @@ class CompilerBase extends \PhpAot\Core\Translator * @var array */ protected array $classMap = []; + protected int $funcIndex = 0; + protected array $funcMap = []; protected array $zendTypeMap = [ 'int' => self::TYPE_INT, @@ -668,6 +671,18 @@ class CompilerBase extends \PhpAot\Core\Translator return 'php_get_class_entry(' . $id . ', "' . $this->escapeString($className) . '")'; } + protected function getFuncPtr(string $funcName): string + { + if (isset($this->funcMap[$funcName])) { + $id = $this->funcMap[$funcName]; + } else { + $id = $this->funcIndex++; + $this->funcMap[$funcName] = $id; + } + + return 'php_get_func(' . $id . ', "' . $this->escapeString($funcName) . '")'; + } + protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef { // .stub 存根定义 C++ Native 函数,必须设置返回值类型 @@ -1777,15 +1792,11 @@ class CompilerBase extends \PhpAot\Core\Translator if ($nativeFn) { return self::PREFIX . $nativeFn . '(' . $this->parseNativeCallArgs($expr->args, $nativeFn) . ')'; } - if ($this->isInternalFunction($name)) { - $fn = 'php::' . $name; - } else { - $fn = '"' . $name . '"'; - } $code = $this->parseFuncCallWithOptimizer($name, $expr); if ($code) { return $code; } + $fn = $this->getFuncPtr($name); } else { $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); @@ -1794,6 +1805,7 @@ class CompilerBase extends \PhpAot\Core\Translator $name = ''; } $call = $silent ? 'php::silentCall' : 'php::call'; + if (empty($expr->args)) { return $call . '(' . $fn . ')'; } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 69aff2fc..d4cbb09c 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -210,6 +210,9 @@ class Translator extends Preprocessor $classEntryCount = count($this->classMap); $lines[] = 'extern zend_class_entry *' . self::PREFIX . self::CLASS_ENTRY_MAP . '[' . $classEntryCount . '];' . PHP_EOL; + $funcCount = count($this->funcMap); + $lines[] = 'extern zend_function *' . self::PREFIX . self::FUNC_MAP . '[' . $funcCount . '];' . PHP_EOL; + $code = implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; $this->writeFile($file, $code); } @@ -301,6 +304,7 @@ class Translator extends Preprocessor } $code .= 'extern zend_class_entry *php_get_class_entry(int class_id, const char *class_name);' . PHP_EOL; + $code .= 'extern zend_function *php_get_func(int func_id, const char *func_name);' . PHP_EOL; $this->writeFile($file, $code); } diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index da872bf9..4b6a406e 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -24,6 +24,9 @@ zend_class_entry * ; // class entry zend_class_entry *classMap) . ']' ?>; +// func +zend_function *funcMap) . ']' ?>; + zend_class_entry *php_get_class_entry(int class_id, const char *class_name) { if (UNEXPECTED([class_id] == nullptr)) { [class_id] = php::getClassEntrySafe(class_name); @@ -31,6 +34,13 @@ zend_class_entry *php_get_class_entry(int class_id, const char *class_name) { return [class_id]; } +zend_function *php_get_func(int func_id, const char *func_name) { + if (UNEXPECTED([func_id] == nullptr)) { + [func_id] = php::getFunction(func_name); + } + return [func_id]; +} + // literal strings php::Var [] = {