refactor(php): 优化PHP编译器代码结构和功能实现

- 修复AstNodeType中isAssignOp方法的命名空间引用问题
- 移除class-static-002测试用例中的多余输出断言
- 在CompilerBase中添加objectWrappers和ceWrappers属性用于对象包装器管理
- 新增getCeWrapper方法用于获取类入口包装器
- 修改注释格式从文档块改为行注释以提升性能
- 移除hasNativeClass和hasNativeFunction的返回值类型注解
- 重构parseArrayMixed方法的位置,从私有方法调整为类末尾重新定义
- 简化魔术常量解析中的字符串拼接逻辑
- 优化静态调用处理,支持static关键字的正确解析
- 添加addTmpVar辅助方法用于临时变量创建
- 统一字符串字面量的引号使用规范
pull/1/head
韩天峰 6 months ago
parent d0d66a0982
commit cebe50121a
  1. 2
      src/Php/AstNodeType.php
  2. 119
      src/Php/CompilerBase.php
  3. 10
      src/Php/Generator/PropertyPromotion.php
  4. 1
      tests/aot/class-static-002.phpt

@ -86,6 +86,6 @@ trait AstNodeType
protected function isAssignOp(NodeAbstract $expr): bool
{
return $expr instanceof Node\Expr\AssignOp or $expr instanceof Node\Expr\Assign;
return $expr instanceof Expr\AssignOp or $expr instanceof Expr\Assign;
}
}

@ -112,6 +112,7 @@ class CompilerBase extends \PhpAot\Core\Translator
'php_aot_helper.h',
];
protected array $localHeaders = [];
/**
* 存储所有函数、类方法的定义,key 是 native name,命名空间需要转为 `_`,并且必须为小写
* @var array<string, FunctionDef>
@ -155,6 +156,7 @@ class CompilerBase extends \PhpAot\Core\Translator
* @var array<string, ClassDef>
*/
protected array $classes = [];
/**
* @var array<string, InterfaceDef>
*/
@ -206,7 +208,16 @@ class CompilerBase extends \PhpAot\Core\Translator
protected array $objects = [];
protected array $localVars = [];
protected array $staticVars = [];
/**
* @var array<string, string>
*/
protected array $objectWrappers = [];
/**
* @var array<string, string>
*/
protected array $ceWrappers = [];
protected bool $strictTypes = false;
protected string $rootPath;
protected string $buildDir;
@ -697,6 +708,17 @@ class CompilerBase extends \PhpAot\Core\Translator
return 'php_get_class(' . $id . ', ' . $this->getLiteralString($className) . ')';
}
protected function getCeWrapper(string $className): string
{
if (isset($this->ceWrappers[$className])) {
return $this->ceWrappers[$className];
}
$object = $this->addTmpVar(self::TYPE_OBJECT);
$this->beforeStmtLines[] = 'Z_PTR_P(' . $object . '.ptr()) = ' . $this->getClassEntryPtr($className) . ';';
$this->ceWrappers[$className] = $object;
return $object;
}
protected function getFuncPtr(string $funcName, bool $macro = true): string
{
$id = $this->getFuncId($funcName);
@ -915,7 +937,7 @@ class CompilerBase extends \PhpAot\Core\Translator
if (!$default) {
return null;
}
/**
/*
* 函数参数默认值只能为字面量,无法使用表达式获取值
*/
if ($default instanceof Node\Expr\ConstFetch) {
@ -1417,6 +1439,13 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->localVars[$name] = $type;
}
protected function addTmpVar(string $type): string
{
$var = $this->genTmpVarName();
$this->addLocalVar($var, $type);
return $var;
}
protected function addStaticVar(string $name, string $type): void
{
$this->staticVars[$name] = $type;
@ -1464,7 +1493,6 @@ class CompilerBase extends \PhpAot\Core\Translator
/**
* @param string $name 必须传入带有完整命名空间的类名,将会自动转义为 native name
* @return bool
*/
protected function hasNativeClass(string $name): bool
{
@ -1473,7 +1501,6 @@ class CompilerBase extends \PhpAot\Core\Translator
/**
* @param string $name 必须传入带有完整命名空间的类名,将会自动转义为 native name
* @return bool
*/
protected function hasNativeFunction(string $name): bool
{
@ -1592,38 +1619,6 @@ class CompilerBase extends \PhpAot\Core\Translator
return self::TYPE_VAR;
}
/**
* 混杂数组赋值,需要拆分为多行插入
*/
private function parseArrayMixed(Node\Expr\Array_ $node): string
{
$tmpVar = $this->genTmpVarName();
$this->addLocalVar($tmpVar, self::TYPE_ARRAY);
$items = $node->items;
foreach ($items as $item) {
$value = $this->parseIdentifier($item->value);
if ($item->unpack) {
$this->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.merge(' . $value . ');';
} elseif ($item->key) {
$key = $this->parseIdentifier($item->key);
if (str_starts_with($key, self::LITERAL_STRINGS)) {
$key = "{$key}.toStdString()";
} elseif ($key === '0L') {
$key = 'php::zero';
}
$this->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.set(' . $key . ', ' . $value . ');';
} else {
$this->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.append(' . $value . ');';
}
}
// 释放临时变量,避免修改数组产生数组复制操作
$this->afterStmtLines[] = $this->getIndent() . $tmpVar . '.unset();';
return $tmpVar;
}
protected function parseArray(Node\Expr\Array_ $node): string
{
$items = $node->items;
@ -2057,9 +2052,6 @@ class CompilerBase extends \PhpAot\Core\Translator
/**
* 查找原生函数.
*
* @param string $fname
* @return string|false
*/
protected function findNativeFunction(string $fname): string|false
{
@ -2911,8 +2903,8 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseMagicConst(MagicConst $expr): string
{
$class = ($this->namespace ? $this->namespace . '\\' : '') . $this->class;
$function = ($this->namespace ? $this->namespace . '\\' : '') . $this->function;
$class = ($this->namespace ? $this->namespace . '\\' : '') . $this->class;
$function = ($this->namespace ? $this->namespace . '\\' : '') . $this->function;
switch ($expr->getType()) {
case 'Scalar_MagicConst_Dir':
return '"' . $this->escapeString($this->dir) . '"';
@ -3407,7 +3399,7 @@ class CompilerBase extends \PhpAot\Core\Translator
}
return $id;
}
/**
/*
* 对 static 的支持存在问题,静态编译时无法获得实际运行时的子类名,所以只能使用 self
* self 是在编译期确定的,而 static 是运行时确定的,但使用 AOT 编译为可执行文件后,运行时类的名称是无法确定的
*/
@ -3433,8 +3425,10 @@ class CompilerBase extends \PhpAot\Core\Translator
{
$self = false;
$callScope = [];
$class = $this->parseIdentifier($expr->class);
if ($this->isVarExpr($expr->class) or $this->isVarExpr($expr->name)) {
$var = $this->parseIdentifier($expr->class);
$var = $class;
if ($this->isTypedObject($var)) {
$class = $this->getObjectType($var);
goto _do_call;
@ -3445,8 +3439,11 @@ class CompilerBase extends \PhpAot\Core\Translator
$fn = 'php::concat({' . $this->identifierToStr($expr->class) . ', "::", ' . $this->identifierToStr($expr->name) . '})';
}
$placeHolder = $fn;
} elseif ($class === 'static') {
$methodPtr = $this->identifierToStr($expr->name);
$fn = 'php_get_called_ce(this_), php::getMethod(php_get_called_ce(this_), ' . $methodPtr . ')';
$placeHolder = $this->genArray(['php_get_called_class(this_)', $methodPtr]);
} else {
$class = $this->parseIdentifier($expr->class);
if ($class === 'self') {
$class = $this->class;
$self = true;
@ -3475,9 +3472,7 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($this->methodDef and $self) {
$object = 'this_';
} else {
$object = $this->genTmpVarName();
$this->addLocalVar($object, self::TYPE_OBJECT);
$this->beforeStmtLines[] = 'Z_PTR_P('.$object.'.ptr()) = ' . $this->getClassEntryPtr($class) . ';';
$object = $this->getCeWrapper($class);
}
if ($args) {
return self::PREFIX . $nativeFunc . '(' . $object . ', ' . $args . ')';
@ -4032,4 +4027,36 @@ class CompilerBase extends \PhpAot\Core\Translator
}
return $stmts[array_key_last($stmts)] instanceof Node\Stmt\Return_;
}
/**
* 混杂数组赋值,需要拆分为多行插入
*/
private function parseArrayMixed(Node\Expr\Array_ $node): string
{
$tmpVar = $this->genTmpVarName();
$this->addLocalVar($tmpVar, self::TYPE_ARRAY);
$items = $node->items;
foreach ($items as $item) {
$value = $this->parseIdentifier($item->value);
if ($item->unpack) {
$this->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.merge(' . $value . ');';
} elseif ($item->key) {
$key = $this->parseIdentifier($item->key);
if (str_starts_with($key, self::LITERAL_STRINGS)) {
$key = "{$key}.toStdString()";
} elseif ($key === '0L') {
$key = 'php::zero';
}
$this->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.set(' . $key . ', ' . $value . ');';
} else {
$this->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.append(' . $value . ');';
}
}
// 释放临时变量,避免修改数组产生数组复制操作
$this->afterStmtLines[] = $this->getIndent() . $tmpVar . '.unset();';
return $tmpVar;
}
}

@ -1,4 +1,10 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Generator;
@ -9,8 +15,8 @@ trait PropertyPromotion
protected function genPropertyPromotion(ArgInfo $argInfo): string
{
$code = '';
$code .= "this_.setProperty(" . $this->genCharPtr($argInfo->name) . ", " . $argInfo->name . ")";
$code .= 'this_.setProperty(' . $this->genCharPtr($argInfo->name) . ', ' . $argInfo->name . ')';
$code .= ";\n";
return $code;
}
}
}

@ -37,4 +37,3 @@ namespace {
--EXPECT--
string(5) "hello"
string(5) "world"
string(3) "foo"

Loading…
Cancel
Save