From d8e164b32c9b8ef94125228ee8fdca6b2b48133b Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 5 Mar 2026 11:48:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(aot):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9static?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=AD=97=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了static::method()静态方法调用的编译支持 - 添加了new static()动态实例化的处理逻辑 - 增加了static属性访问的正确解析 - 添加了两个新的AOT测试用例验证static功能 - 实现了延迟解析以支持后期绑定行为 --- src/Php/CompilerBase.php | 19 ++++++++++++--- tests/aot/class-static-003.phpt | 34 ++++++++++++++++++++++++++ tests/aot/class-static-004.phpt | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 tests/aot/class-static-003.phpt create mode 100644 tests/aot/class-static-004.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 1ad5dd83..be07b659 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2653,15 +2653,25 @@ class CompilerBase extends \PhpAot\Core\Translator $this->beforeStmtLines[] = 'if (!' . $className . '_defined) {' . $className . '_defined = true; php::eval((const char *)' . $className . '_code);}'; $className = '\\' . $className; + $cePtr = $this->getClassEntryPtr($className); } else { $this->fatalError($expr, 'must be anonymous class'); } } else { $className = $this->parseIdentifier($expr->class); + if ($this->isNameExpr($expr->class)) { + if ($className === 'static') { + $cePtr = 'php_get_called_ce(this_)'; + } else { + $className = $this->getNamespacedClassName($className); + $cePtr = $this->getClassEntryPtr($className); + } + } else { + $cePtr = $className; + } } - $className = $this->getNamespacedClassName($className); - $args = $expr->args; - $cePtr = $this->getClassEntryPtr($className); + + $args = $expr->args; if (empty($args)) { return 'php::newObject(' . $cePtr . ')'; } @@ -3440,8 +3450,9 @@ class CompilerBase extends \PhpAot\Core\Translator } $placeHolder = $fn; } elseif ($class === 'static') { - $methodPtr = $this->identifierToStr($expr->name); + $methodPtr = $this->identifierToStr($expr->name, literal: true); $fn = 'php_get_called_ce(this_), php::getMethod(php_get_called_ce(this_), ' . $methodPtr . ')'; + $this->beforeStmtLines[] = '// Static Method Call: static::' . $this->parseIdentifier($expr->name) . '()'; $placeHolder = $this->genArray(['php_get_called_class(this_)', $methodPtr]); } else { if ($class === 'self') { diff --git a/tests/aot/class-static-003.phpt b/tests/aot/class-static-003.phpt new file mode 100644 index 00000000..c8246240 --- /dev/null +++ b/tests/aot/class-static-003.phpt @@ -0,0 +1,34 @@ +--TEST-- +class static 003 +--FILE-- + +--EXPECT-- +string(12) "Test\Worker2" diff --git a/tests/aot/class-static-004.phpt b/tests/aot/class-static-004.phpt new file mode 100644 index 00000000..e3a583bc --- /dev/null +++ b/tests/aot/class-static-004.phpt @@ -0,0 +1,43 @@ +--TEST-- +class static 004 +--FILE-- + +--EXPECT-- +string(5) "hello" +string(6) "swoole" +string(5) "hello" +string(5) "world" +