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"