refactor(php): 重构PHP编译器函数声明解析和包装生成逻辑

- 修改parseFunctionDeclaration方法移除name参数,直接从节点获取函数名
- 修复错误消息中的变量引用,使用$v->name替代传入的$name参数
- 统一FunctionDef创建时的名称解析,使用parseIdentifier处理节点名称
- 更新parseFunctionDeclaration调用处,传递节点对象而非名称字符串
- 重命名genMethodWrapper为genWrapperFunctionArgs并重构参数处理逻辑
- 添加对方法和函数的不同参数处理逻辑,区分是否包含this_参数
- 重构genMethodWrapper方法以复用新的genWrapperFunctionArgs功能
- 在Constants.php中添加char关键字到保留字列表
pull/1/head
韩天峰 7 months ago
parent d3360d2f38
commit cf5e889a75
  1. 8
      src/Php/CompilerBase.php
  2. 1
      src/Php/Constants.php
  3. 2
      src/Php/Preprocessor.php
  4. 54
      src/Php/Translator.php

@ -276,14 +276,14 @@ class CompilerBase extends \PhpAot\Core\Translator
return implode(self::NAMESPACE_SEPARATOR, array_reverse($names));
}
protected function parseFunctionDeclaration(string $name, Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef
protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef
{
$returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID;
// .stub 存根定义 C++ Native 函数,必须设置返回值类型
if ($returnType === self::TYPE_VOID && $this->stubFile) {
throw new Exception('No return type for ' . $name);
throw new Exception('No return type for ' . $v->name);
}
$functionDef = new FunctionDef($name, $returnType);
$functionDef = new FunctionDef($this->parseIdentifier($v->name), $returnType);
$this->functionDef = $functionDef;
$this->parseParams($v->params, $functionDef);
return $functionDef;
@ -297,7 +297,7 @@ class CompilerBase extends \PhpAot\Core\Translator
if (isset($this->nativeFunctions[$name])) {
$this->functionDef = $this->nativeFunctions[$name];
} else {
$this->nativeFunctions[$name] = $this->parseFunctionDeclaration($name, $v);
$this->nativeFunctions[$name] = $this->parseFunctionDeclaration($v);
if (isset($this->redoAfterDeclare[$name])) {
unset($this->redoAfterDeclare[$name]);
$this->climate->cyan('Received redo request, retrying...');

@ -35,6 +35,7 @@ class Constants
'new',
'null',
'var',
'char',
'or',
'and',
'private',

@ -140,7 +140,7 @@ class Preprocessor extends CompilerBase
{
$name = $this->getFunctionName($v);
if ($this->stubFile) {
$this->nativeFunctions[$name] = $this->parseFunctionDeclaration($name, $v);
$this->nativeFunctions[$name] = $this->parseFunctionDeclaration($v);
} else {
$this->functionDeclInFile[$name] = $this->file;
}

@ -657,15 +657,11 @@ class Translator extends Preprocessor
return $code;
}
protected function genMethodWrapper(ClassDef $classDef, MethodDef $methodDef): string
protected function genWrapperFunctionArgs(string $fn, FunctionDef $functionDef): 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);
$cppCode = '';
$callParams = '';
foreach ($methodDef->functionDef->argInfoList as $k => $argInfo) {
foreach ($functionDef->argInfoList as $k => $argInfo) {
if ($argInfo->default) {
$argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')';
} else {
@ -675,9 +671,14 @@ class Translator extends Preprocessor
$cppCode .= $this->getIndent() . $argInfo->type . ' arg_' . $argInfo->name . ' = ' . $expr . ';' . PHP_EOL;
$callParams .= 'arg_' . $argInfo->name . ',';
}
$callParams = $methodDef->functionDef->argInfoList ? 'this_, ' . rtrim($callParams, ',') : 'this_';
if ($methodDef->getReturnType() !== self::TYPE_VOID) {
if ($functionDef->method) {
$callParams = $functionDef->argInfoList ? 'this_, ' . rtrim($callParams, ',') : 'this_';
} else {
$callParams = $functionDef->argInfoList ? rtrim($callParams, ',') : '';
}
if ($functionDef->returnType !== self::TYPE_VOID) {
$cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(' . $callParams . ');' . PHP_EOL;
$cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL;
} else {
@ -688,33 +689,22 @@ class Translator extends Preprocessor
return $cppCode;
}
private function genFunctionWrapper(FunctionDef $functionDef)
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);
$cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef);
return $cppCode;
}
private function genFunctionWrapper(FunctionDef $functionDef): string
{
$name = $functionDef->name;
$cppCode = 'ZEND_FUNCTION(' . $name . '){' . PHP_EOL;
$fn = self::PREFIX . $this->getNativeName($functionDef->name);
$callParams = '';
foreach ($functionDef->argInfoList as $k => $argInfo) {
if ($argInfo->default) {
$argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')';
} else {
$argExpr = 'php::getCallArg(' . $k . ')';
}
$expr = $this->convertExprFromType($argInfo->type, $argExpr);
$cppCode .= $this->getIndent() . $argInfo->type . ' arg_' . $argInfo->name . ' = ' . $expr . ';' . PHP_EOL;
$callParams .= 'arg_' . $argInfo->name . ',';
}
$callParams = $functionDef->argInfoList ? rtrim($callParams, ',') : '';
if ($functionDef->returnType !== self::TYPE_VOID) {
$cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(' . $callParams . ');' . PHP_EOL;
$cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL;
} else {
$cppCode .= $this->getIndent() . $fn . '(' . $callParams . ');' . PHP_EOL;
}
$cppCode .= '}' . PHP_EOL . PHP_EOL;
$cppCode .= $this->genWrapperFunctionArgs($fn, $functionDef);
return $cppCode;
}

Loading…
Cancel
Save