From e230e66164ee06a35eb75999e85e5da7b028c7d1 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 25 Mar 2026 18:28:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=94=AF=E6=8C=81=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E5=8F=82=E6=95=B0=E7=9A=84=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=E4=B8=BA=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 isEmptyArray 方法检查空数组 - 修改编译器对引用参数默认值的处理逻辑 - 实现引用参数默认值为空数组的支持 - 更新参数解析逻辑以正确处理引用参数 - 添加测试用例验证引用参数数组默认值功能 - 修复命名参数缺失默认值时的错误处理 --- src/Php/AstNodeType.php | 5 +++++ src/Php/CompilerBase.php | 15 ++++++++++++--- src/Php/Translator.php | 6 +++++- tests/aot/ref/default-array.phpt | 29 +++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 tests/aot/ref/default-array.phpt diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index 13fdf74c..e5e7baad 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -129,4 +129,9 @@ trait AstNodeType } return $expr instanceof Expr\Exit_; } + + protected function isEmptyArray(NodeAbstract $expr): bool + { + return $expr instanceof Node\Expr\Array_ && count($expr->items) === 0; + } } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index ebc75a9a..94de34e9 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1031,11 +1031,17 @@ class CompilerBase extends \PhpAot\Core\Translator } if ($param->default) { if ($param->byRef) { - $this->fatalError($param, 'Default value for parameters passed by reference is not supported'); + if (!$this->isEmptyArray($param->default)) { + $this->fatalError($param, 'Default value for parameters passed by reference must be an empty array'); + } else { + $argInfo->default = 'php::getEmptyArrayRef()'; + $argInfo->defaultValue = null; + } + } else { + $argInfo->default = $this->parseParamDefaultValue($param->default); + $argInfo->defaultValue = $param->default; } $defaultValueCount++; - $argInfo->default = $this->parseParamDefaultValue($param->default); - $argInfo->defaultValue = $param->default; } elseif ($param->variadic) { // 变长参数可以视为空数组默认值 $defaultValueCount++; @@ -2339,6 +2345,9 @@ class CompilerBase extends \PhpAot\Core\Translator // 命名参数中间存在空洞,需要使用默认参数填充 foreach ($functionDef->argInfoList as $k => $argInfo) { if (!isset($args[$k])) { + if ($argInfo->defaultValue === null) { + $this->fatalError($callArgs[$i], 'Named argument `' . $argInfo->name . '` is missing default value'); + } $args[$k] = new Node\Arg($argInfo->defaultValue); } } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 391332a3..0f8b3adc 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -954,7 +954,11 @@ class Translator extends Preprocessor $cppCode .= '}' . PHP_EOL; } else { if ($argInfo->default) { - $argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')'; + if ($argInfo->byRef) { + $argExpr = 'php::getCallArgByRef(' . $k . ', ' . $argInfo->default . ')'; + } else { + $argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')'; + } } else { if ($argInfo->byRef) { $argExpr = 'php::getCallArgByRef(' . $k . ')'; diff --git a/tests/aot/ref/default-array.phpt b/tests/aot/ref/default-array.phpt new file mode 100644 index 00000000..350a70a5 --- /dev/null +++ b/tests/aot/ref/default-array.phpt @@ -0,0 +1,29 @@ +--TEST-- +ref call arg +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + string(13) "%s" +} +array(2) { + [0]=> + string(13) "%s" + [1]=> + string(13) "%s" +} \ No newline at end of file