test(aot): 添加大整数、大浮点数、十进制数和流类型的容器测试

- 添加 std-bigfloat 类型的 vector 容器功能测试
- 添加 std-bigint 类型的 vector、map、array 和 foreach 功能测试
- 添加 std-decimal 类型的 vector 容器功能测试
- 添加 std-stream 类型的 vector 容器功能测试
- 实现容器元素类型转换逻辑支持大数值类型
- 修复容器声明中的元素类型转换问题
- 添加新的原生类型映射支持 bigint、bigfloat、decimal 和 stream 类型
pull/1/head
韩天峰 3 months ago
parent 11acfdf10f
commit 011cb1ed8c
  1. 45
      src/Php/Parser/StdContainerParser.php
  2. 22
      tests/aot/std-bigfloat/001.phpt
  3. 22
      tests/aot/std-bigint/001.phpt
  4. 22
      tests/aot/std-bigint/002.phpt
  5. 20
      tests/aot/std-bigint/003.phpt
  6. 20
      tests/aot/std-bigint/004.phpt
  7. 22
      tests/aot/std-decimal/001.phpt
  8. 34
      tests/aot/std-stream/001.phpt

@ -103,7 +103,7 @@ trait StdContainerParser
protected function getStdArrayDecl(string $type, array $sizes): string protected function getStdArrayDecl(string $type, array $sizes): string
{ {
$decl = str_repeat(self::TYPE_STD_ARRAY . '<', count($sizes)); $decl = str_repeat(self::TYPE_STD_ARRAY . '<', count($sizes));
$decl .= $type; $decl .= $this->getStdContainerElementType($type);
for ($i = count($sizes) - 1; $i >= 0; $i--) { for ($i = count($sizes) - 1; $i >= 0; $i--) {
$decl .= ', ' . $sizes[$i] . '>'; $decl .= ', ' . $sizes[$i] . '>';
} }
@ -454,6 +454,14 @@ trait StdContainerParser
return $this->convertIntExpr($index); return $this->convertIntExpr($index);
} }
protected function getStdContainerElementType(string $type): string
{
return match ($type) {
self::TYPE_BIGINT, self::TYPE_BIGFLOAT, self::TYPE_DECIMAL, self::TYPE_STREAM => self::TYPE_VAR,
default => $type,
};
}
protected function parseStdNativeType(NodeAbstract $expr, string $owner): string protected function parseStdNativeType(NodeAbstract $expr, string $owner): string
{ {
if (!$this->isClassConstFetch($expr)) { if (!$this->isClassConstFetch($expr)) {
@ -466,6 +474,9 @@ trait StdContainerParser
'type_int' => self::TYPE_INT, 'type_int' => self::TYPE_INT,
'type_float' => self::TYPE_FLOAT, 'type_float' => self::TYPE_FLOAT,
'type_bool' => self::TYPE_BOOL, 'type_bool' => self::TYPE_BOOL,
'type_bigint' => self::TYPE_BIGINT,
'type_bigfloat' => self::TYPE_BIGFLOAT,
'type_decimal' => self::TYPE_DECIMAL,
default => $this->fatalError($expr, "An incorrect `{$owner}` definition"), default => $this->fatalError($expr, "An incorrect `{$owner}` definition"),
}; };
} }
@ -488,6 +499,7 @@ trait StdContainerParser
'type_array' => self::TYPE_ARRAY, 'type_array' => self::TYPE_ARRAY,
'type_object' => self::TYPE_OBJECT, 'type_object' => self::TYPE_OBJECT,
'type_any', 'type_var', 'type_variant' => self::TYPE_VAR, 'type_any', 'type_var', 'type_variant' => self::TYPE_VAR,
'type_stream' => self::TYPE_STREAM,
default => $this->fatalError($expr, "An incorrect `{$owner}` definition"), default => $this->fatalError($expr, "An incorrect `{$owner}` definition"),
}, },
'class' => null, 'class' => null,
@ -538,7 +550,11 @@ trait StdContainerParser
$valueExpr = $this->parseExpr($expr); $valueExpr = $this->parseExpr($expr);
$class = $info['class'] ?? null; $class = $info['class'] ?? null;
if ($class === null) { if ($class === null) {
return $this->convertExprFromType($info['type'], $valueExpr); $targetType = $info['type'];
if ($targetType === self::TYPE_BIGINT || $targetType === self::TYPE_BIGFLOAT || $targetType === self::TYPE_DECIMAL || $targetType === self::TYPE_STREAM) {
return $this->convertStdVarBackedExpr($targetType, $valueExpr, $expr);
}
return $this->convertExprFromType($targetType, $valueExpr);
} }
$rightClass = $this->detectClassOfExpr($expr); $rightClass = $this->detectClassOfExpr($expr);
if ($rightClass !== '') { if ($rightClass !== '') {
@ -550,6 +566,27 @@ trait StdContainerParser
return 'php::toObject(' . $valueExpr . ', ' . $this->getClassEntryPtr($class) . ', true)'; return 'php::toObject(' . $valueExpr . ', ' . $this->getClassEntryPtr($class) . ', true)';
} }
protected function convertStdVarBackedExpr(string $targetType, string $valueExpr, NodeAbstract $expr): string
{
$sourceType = $this->detectTypeOfExpr($expr);
if ($sourceType === $targetType) {
return $valueExpr;
}
if ($targetType === self::TYPE_STREAM) {
return $valueExpr;
}
if ($targetType === self::TYPE_BIGINT) {
return $this->convertBigIntExpr($valueExpr, $sourceType);
}
if ($targetType === self::TYPE_BIGFLOAT) {
return $this->convertBigFloatExpr($valueExpr, $sourceType);
}
if ($targetType === self::TYPE_DECIMAL) {
return $this->convertDecimalExpr($valueExpr, $sourceType, $expr);
}
return $valueExpr;
}
protected function parseStdUnsafeCastAssign(string $var, Expr\StaticCall $expr): string protected function parseStdUnsafeCastAssign(string $var, Expr\StaticCall $expr): string
{ {
if (count($expr->args) !== 2) { if (count($expr->args) !== 2) {
@ -608,7 +645,7 @@ trait StdContainerParser
protected function getStdMapDecl(string $containerType, string $keyType, string $valueType): string protected function getStdMapDecl(string $containerType, string $keyType, string $valueType): string
{ {
return $containerType . '<' . $keyType . ', ' . $valueType . '>'; return $containerType . '<' . $keyType . ', ' . $this->getStdContainerElementType($valueType) . '>';
} }
protected function parseStdArray(string $var, Expr\StaticCall $expr): string protected function parseStdArray(string $var, Expr\StaticCall $expr): string
@ -671,7 +708,7 @@ trait StdContainerParser
} }
$size = $expr->args[1]->value->value; $size = $expr->args[1]->value->value;
} }
$decl = self::TYPE_STD_VECTOR . '<' . $type . '>'; $decl = self::TYPE_STD_VECTOR . '<' . $this->getStdContainerElementType($type) . '>';
$this->context->stdContainers[$var] = $this->addStdTypeId([ $this->context->stdContainers[$var] = $this->addStdTypeId([
'kind' => 'vector', 'kind' => 'vector',
'decl' => $decl, 'decl' => $decl,

@ -0,0 +1,22 @@
--TEST--
std bigfloat: vector push_back and read
--FILE--
<?php
function main() {
$v = std::vector(native_types::type_bigfloat);
$v[] = 3.14;
$v[] = 2.71;
$v[] = 100;
var_dump($v[0]->toString());
var_dump($v[1]->toString());
var_dump($v[2]->toString());
var_dump(count($v));
}
?>
--EXPECT--
string(18) "3.1400000000000001"
string(4) "2.71"
string(3) "100"
int(3)

@ -0,0 +1,22 @@
--TEST--
std bigint: vector push_back and read
--FILE--
<?php
function main() {
$v = std::vector(native_types::type_bigint);
$v[] = 99;
$v[] = 88;
$v[] = 77;
var_dump($v[0]->toString());
var_dump($v[1]->toString());
var_dump($v[2]->toString());
var_dump(count($v));
}
?>
--EXPECT--
string(2) "99"
string(2) "88"
string(2) "77"
int(3)

@ -0,0 +1,22 @@
--TEST--
std bigint: map set/get
--FILE--
<?php
function main() {
$m = std::map(native_types::type_int, native_types::type_bigint);
$m[1] = 100;
$m[2] = 200;
$m[3] = 300;
var_dump($m[1]->toString());
var_dump($m[2]->toString());
var_dump($m[3]->toString());
var_dump(count($m));
}
?>
--EXPECT--
string(3) "100"
string(3) "200"
string(3) "300"
int(3)

@ -0,0 +1,20 @@
--TEST--
std bigint: array write/read
--FILE--
<?php
function main() {
$a = std::array(native_types::type_bigint, 5);
$a[0] = 42;
$a[1] = 84;
$a[2] = 126;
var_dump($a[0]->toString());
var_dump($a[1]->toString());
var_dump($a[2]->toString());
}
?>
--EXPECT--
string(2) "42"
string(2) "84"
string(3) "126"

@ -0,0 +1,20 @@
--TEST--
std bigint: foreach
--FILE--
<?php
function main() {
$v = std::vector(native_types::type_bigint);
$v[] = 10;
$v[] = 20;
$v[] = 30;
$sum = 0;
foreach ($v as $k => $val) {
$sum = $sum + $val->toInt();
}
var_dump($sum);
}
?>
--EXPECT--
int(60)

@ -0,0 +1,22 @@
--TEST--
std decimal: vector push_back and read
--FILE--
<?php
function main() {
$v = std::vector(native_types::type_decimal);
$v[] = 3.14;
$v[] = 2.5;
$v[] = 100;
var_dump($v[0]->toString());
var_dump($v[1]->toString());
var_dump($v[2]->toString());
var_dump(count($v));
}
?>
--EXPECT--
string(4) "3.14"
string(3) "2.5"
string(3) "100"
int(3)

@ -0,0 +1,34 @@
--TEST--
std stream: vector push_back and use
--FILE--
<?php
function main() {
$v = std::vector(complex_types::type_stream);
$tmpfile = tempnam(sys_get_temp_dir(), 'aot');
$fp = fopen($tmpfile, 'w+');
$fp->write("hello");
$v[] = $fp;
$fp2 = fopen($tmpfile, 'r');
$v[] = $fp2;
var_dump(count($v));
$r = $v[0];
$r->seek(0);
var_dump($r->read(5));
$r2 = $v[1];
var_dump($r2->read(5));
$v[0]->close();
$v[1]->close();
unlink($tmpfile);
}
?>
--EXPECT--
int(2)
string(5) "hello"
string(5) "hello"
Loading…
Cancel
Save