From 32ac23630a4aae8aba6afe864911d2afde900624 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 1 Jun 2026 19:33:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(type):=20=E4=BF=AE=E5=A4=8Dstream=E5=92=8Cb?= =?UTF-8?q?ox=E4=BC=AA=E7=B1=BB=E5=9E=8B=E7=9A=84=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除CompilerBase中对stream/box类型的硬编码转换逻辑 - 在Preprocessor中添加stream/box到var类型的运行时转换 - 修改Translator中参数类型的C++代码生成逻辑 - 更新UniversalMethodCall中stream/box类型的参数匹配规则 - 添加测试用例验证数组元素链式调用的类型转换功能 --- src/Php/CompilerBase.php | 4 ---- src/Php/Preprocessor.php | 6 +++++- src/Php/Translator.php | 3 ++- src/Php/UniversalMethodCall.php | 6 +++--- tests/aot/var_convert/002.phpt | 21 +++++++++++++++++++++ 5 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 tests/aot/var_convert/002.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 044eaf14..13a3e17c 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2713,10 +2713,6 @@ class CompilerBase extends \PhpAot\Core\Translator } $class = ''; $type = $this->parseTypeDecl($param->type, self::DECL_TYPE_OF_PARAM, $class); - // stream/box 是伪类型,实际运行时依然作为 var 处理 - if ($type === self::TYPE_STREAM || $type === self::TYPE_BOX) { - $type = self::TYPE_VAR; - } if ($class and !$this->hasInterface($class) and !$this->isAbstractClass($class)) { $argInfo->class = $class; } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index ea60e5d1..51aa1e27 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -63,7 +63,11 @@ class Preprocessor extends CompilerBase protected function genArgumentDeclaration(ArgInfo $argInfo): string { - return $argInfo->type . ' ' . $argInfo->name; + $type = $argInfo->type; + if ($type === self::TYPE_STREAM || $type === self::TYPE_BOX) { + $type = self::TYPE_VAR; + } + return $type . ' ' . $argInfo->name; } public function getCppFile(string $file): string diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 2b73679a..7a0e1c86 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -1948,8 +1948,9 @@ CODE; $argExpr = 'php::getCallArg(' . $k . ')'; } } + $cppType = ($argInfo->type === self::TYPE_STREAM || $argInfo->type === self::TYPE_BOX) ? self::TYPE_VAR : $argInfo->type; $expr = $this->convertExprFromType($argInfo->type, $argExpr); - $cppCode .= $this->getIndent() . $argInfo->type . ' ' . $var . ' = ' . $expr . ';' . PHP_EOL; + $cppCode .= $this->getIndent() . $cppType . ' ' . $var . ' = ' . $expr . ';' . PHP_EOL; } $callParams .= 'arg_' . $argInfo->name . ','; } diff --git a/src/Php/UniversalMethodCall.php b/src/Php/UniversalMethodCall.php index 0b31c9d5..53fa712d 100644 --- a/src/Php/UniversalMethodCall.php +++ b/src/Php/UniversalMethodCall.php @@ -474,9 +474,9 @@ trait UniversalMethodCall return false; } $firstParam = $funcDef->argInfoList[0]; - // Stream is a PHP pseudo-type; its params are always untyped (TYPE_VAR) or references - if ($type === self::TYPE_STREAM) { - return $firstParam->byRef || $firstParam->type === self::TYPE_VAR || $firstParam->type === self::TYPE_REF; + // Stream/Box are PHP pseudo-types; their params may be typed or untyped + if ($type === self::TYPE_STREAM || $type === self::TYPE_BOX) { + return $firstParam->byRef || $firstParam->type === self::TYPE_VAR || $firstParam->type === self::TYPE_REF || $firstParam->type === $type; } if ($firstParam->byRef) { return $type === self::TYPE_ARRAY; diff --git a/tests/aot/var_convert/002.phpt b/tests/aot/var_convert/002.phpt new file mode 100644 index 00000000..4fcee25e --- /dev/null +++ b/tests/aot/var_convert/002.phpt @@ -0,0 +1,21 @@ +--TEST-- +var convert chained on array element +--FILE-- +write('world'); +} + +function main() +{ + $pair = stream_socket_pair(AF_UNIX, SOCK_STREAM, 0); + $pair[0]->toStream()->write('hello'); + var_dump($pair[1]->toStream()->read(5)); + + $pair[0]->toStream()->writeTest(); + var_dump($pair[1]->toStream()->read(5)); +} +?> +--EXPECT-- +string(5) "hello" +string(5) "world"