fix(type): 修复stream和box伪类型的类型转换处理

- 移除CompilerBase中对stream/box类型的硬编码转换逻辑
- 在Preprocessor中添加stream/box到var类型的运行时转换
- 修改Translator中参数类型的C++代码生成逻辑
- 更新UniversalMethodCall中stream/box类型的参数匹配规则
- 添加测试用例验证数组元素链式调用的类型转换功能
pull/1/head
韩天峰 3 months ago
parent 3f9c76df5d
commit 32ac23630a
  1. 4
      src/Php/CompilerBase.php
  2. 6
      src/Php/Preprocessor.php
  3. 3
      src/Php/Translator.php
  4. 6
      src/Php/UniversalMethodCall.php
  5. 21
      tests/aot/var_convert/002.phpt

@ -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;
}

@ -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

@ -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 . ',';
}

@ -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;

@ -0,0 +1,21 @@
--TEST--
var convert chained on array element
--FILE--
<?php
function stream_write_test(stream $stream) {
$stream->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"
Loading…
Cancel
Save