From b8516b6ac0609b940df5147db0464fb1790c0658 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 7 Apr 2026 16:34:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E5=AD=98?= =?UTF-8?q?=E6=A0=B9=E6=96=87=E4=BB=B6=E5=87=BD=E6=95=B0=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=92=8C=E7=B1=BB=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复存根文件中魔术方法(__construct/__destruct/__clone)不需要声明返回类型的问题 - 在FunctionDef构造函数中添加stub参数传递 - 修正main函数参数类型检查逻辑,添加逻辑非运算符 - 移除类方法中重复的'this_'参数添加,在stub函数处理后重新添加 - 添加stub函数的特殊处理逻辑,无具体实现时重置函数定义 - 修复类方法名称处理中的变量引用问题 --- examples/project/ext.cc | 13 +++++++++++++ examples/project/ext.stub.php | 10 ++++++++++ examples/project/main.php | 6 +++++- src/Php/CompilerBase.php | 24 ++++++++++++++++++------ src/Php/Entity/FunctionDef.php | 10 ++++++---- src/Php/Preprocessor.php | 3 ++- 6 files changed, 54 insertions(+), 12 deletions(-) diff --git a/examples/project/ext.cc b/examples/project/ext.cc index 76e0f990..71df61d0 100644 --- a/examples/project/ext.cc +++ b/examples/project/ext.cc @@ -1,4 +1,5 @@ #include +#include #include "phpx_func.h" using namespace php; @@ -9,3 +10,15 @@ Int php_fn_test(Int a, Int b) { var_dump(php_uname()); return c; } + +static php::Str prop_base {ZEND_STRL("base"), true}; + +void php_foo____construct(php::Object& this_, php::Int value) { + std::cout << "hashCode: " << prop_base.str()->h << "\n"; + this_.setProperty(prop_base, value); +} + +php::Int php_foo__bar(php::Object &this_, php::Int a, php::Int b) { + std::cout << "hashCode: " << prop_base.str()->h << "\n"; + return this_.getProperty(prop_base).toInt() + a + b; +} \ No newline at end of file diff --git a/examples/project/ext.stub.php b/examples/project/ext.stub.php index bc4e03a1..54d1f996 100644 --- a/examples/project/ext.stub.php +++ b/examples/project/ext.stub.php @@ -1,4 +1,14 @@ bar(123, 342)); } \ No newline at end of file diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 4f5ec4dd..75c5ed4d 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -804,8 +804,12 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseFunctionDecl(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef { // .stub 存根定义 C++ Native 函数,必须设置返回值类型 - if (!$v->returnType && $this->stubFile) { - $this->fatalError($v, 'The return type of the function `' . $v->name . '` must be specified'); + if ($this->stubFile and !$v->returnType) { + // 以下魔术方法都不能声明返回值类型 __construct()/__destruct()/__clone() + if (($this->method and !in_array($this->method, ['__construct', '__destruct', '__clone'])) or !$this->method) { + $name = $this->class ? $this->class . '::' . $v->name : $v->name; + $this->fatalError($v, 'The return type of the function `' . $name . '` must be specified'); + } } // 返回值不能是引用类型 if ($v->byRef) { @@ -814,7 +818,7 @@ class CompilerBase extends \PhpAot\Core\Translator $fnName = $this->parseIdentifier($v->name); $returnType = $this->parseTypeDecl($v->returnType, self::DECL_TYPE_OF_RETURN); - $functionDef = new FunctionDef($fnName, $returnType, $this->namespace); + $functionDef = new FunctionDef($fnName, $returnType, $this->namespace, $this->stubFile); $this->functionDef = $functionDef; $this->parseParams($v->params, $functionDef); @@ -828,10 +832,10 @@ class CompilerBase extends \PhpAot\Core\Translator if ($returnType !== self::TYPE_VOID) { $this->fatalError($v, 'main function must return void'); } - if ($this->checkArgType($functionDef->argInfoList[0]->type, self::TYPE_INT)) { + if (!$this->checkArgType($functionDef->argInfoList[0]->type, self::TYPE_INT)) { $this->fatalError($v, 'The first parameter of the main function must be of type `int`.'); } - if ($this->checkArgType($functionDef->argInfoList[1]->type, self::TYPE_ARRAY)) { + if (!$this->checkArgType($functionDef->argInfoList[1]->type, self::TYPE_ARRAY)) { $this->fatalError($v, 'The second parameter of the main function must be of type `array`.'); } } @@ -861,7 +865,6 @@ class CompilerBase extends \PhpAot\Core\Translator // 类方法不要保存到 functions 中 if ($this->class) { - $this->addArgument('this_', self::TYPE_OBJECT); if ($this->methodDef) { $this->functionDef->method = true; $this->methodDef->functionDef = $this->functionDef; @@ -870,6 +873,15 @@ class CompilerBase extends \PhpAot\Core\Translator $this->functionDefineInFile[$name] = $this->functionDef; } + // stub 函数,没有函数的具体实现,只有声明,实现在 C++ 或者 .so 中定义 + if ($this->functionDef->stub) { + $this->resetFunction(); + return ''; + } + + if ($this->class) { + $this->addArgument('this_', self::TYPE_OBJECT); + } foreach ($this->functionDef->argInfoList as $argInfo) { $this->addArgument($argInfo->name, $argInfo->type); } diff --git a/src/Php/Entity/FunctionDef.php b/src/Php/Entity/FunctionDef.php index b596b61c..55f33d1e 100644 --- a/src/Php/Entity/FunctionDef.php +++ b/src/Php/Entity/FunctionDef.php @@ -21,15 +21,17 @@ class FunctionDef public array $argInfoList = []; public int $argCountRequired = 0; public string $params = ''; - public string $namespace = ''; + public string $namespace; public bool $method = false; + public bool $stub = false; public bool $completed = false; - public function __construct(string $name, string $returnType, string $namespace = '') + public function __construct(string $name, string $returnType, string $namespace, bool $stub) { - $this->name = $name; + $this->name = $name; $this->returnType = $returnType; - $this->namespace = $namespace; + $this->namespace = $namespace; + $this->stub = $stub; } public function getNamespacedName(): string diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 3689c70a..27a3b38f 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -266,6 +266,7 @@ class Preprocessor extends CompilerBase protected function prepareMethod(Node\Stmt\ClassMethod $v, Node\Stmt\Class_|Node\Stmt\Trait_|Node\Stmt\Enum_ $class): void { + $this->method = $v->name; $abstract = $v->flags & Modifiers::ABSTRACT; if (!$abstract) { $this->prepareFunction($v) . PHP_EOL; @@ -276,7 +277,7 @@ class Preprocessor extends CompilerBase } $fullClassName = $this->getFullClassName(); - $fullMethodName = $fullClassName . '::' . $v->name; + $fullMethodName = $fullClassName . '::' . $this->method; $this->classMethodOverride[strtolower($fullMethodName)] = false; // 查找父类是否有同名方法,递归查找 $fullClassNameLower = strtolower($fullClassName);