feat(php): 添加函数指针映射功能支持

- 新增 FUNC_MAP 常量用于存储函数映射
- 添加 funcIndex 和 funcMap 属性用于函数索引管理
- 实现 getFuncPtr 方法获取函数指针
- 修改函数调用逻辑使用新的函数指针机制
- 在扩展模板中添加函数映射数组声明
- 添加 php_get_func 外部函数声明和实现
- 更新翻译器生成相应的外部函数声明
pull/1/head
韩天峰 7 months ago
parent 100f2e22cb
commit 0e4a332519
  1. 22
      src/Php/CompilerBase.php
  2. 4
      src/Php/Translator.php
  3. 10
      src/template/extension.cc.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<string, int>
*/
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 . ')';
}

@ -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);
}

@ -24,6 +24,9 @@ zend_class_entry * <?= $ce ?>;
// class entry
zend_class_entry *<?= Translator::PREFIX . Translator::CLASS_ENTRY_MAP . '[' . count($this->classMap) . ']' ?>;
// func
zend_function *<?= Translator::PREFIX . Translator::FUNC_MAP . '[' . count($this->funcMap) . ']' ?>;
zend_class_entry *php_get_class_entry(int class_id, const char *class_name) {
if (UNEXPECTED(<?= Translator::PREFIX . Translator::CLASS_ENTRY_MAP ?>[class_id] == nullptr)) {
<?= Translator::PREFIX . Translator::CLASS_ENTRY_MAP ?>[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 <?= Translator::PREFIX . Translator::CLASS_ENTRY_MAP ?>[class_id];
}
zend_function *php_get_func(int func_id, const char *func_name) {
if (UNEXPECTED(<?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id] == nullptr)) {
<?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id] = php::getFunction(func_name);
}
return <?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id];
}
// literal strings
php::Var <?=Translator::LITERAL_STRINGS?>[] = {
<?php

Loading…
Cancel
Save