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