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 [] = {