diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 34b6a5ed..b7a45402 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2464,10 +2464,16 @@ class CompilerBase extends \PhpAot\Core\Translator if ($i !== $last) { $this->fatalError($arg, 'The unpack expression for variadic arguments must be the last'); } - $tmpVar = $this->genTmpVarName(); - $this->context->beforeStmtLines[] = self::TYPE_ARRAY . ' ' . $tmpVar . '{' . implode(', ', $list_args) . '};'; - $this->context->beforeStmtLines[] = $tmpVar . '.merge(' . $this->parseArrayArg($arg) . ');'; - return $tmpVar; + // 如果第一个参数是数组变量,数组展开语法直接传递该变量,没必要创建临时变量 + // 例如:function (array $args) { var_dump(...$args); } + if ($i === 0 and $this->isVarExpr($arg->value) and $this->getVarType($arg->value->name) === self::TYPE_ARRAY) { + return $this->parseIdentifier($arg->value); + } else { + $tmpVar = $this->genTmpVarName(); + $this->context->beforeStmtLines[] = self::TYPE_ARRAY . ' ' . $tmpVar . '{' . implode(', ', $list_args) . '};'; + $this->context->beforeStmtLines[] = $tmpVar . '.merge(' . $this->parseArrayArg($arg) . ');'; + return $tmpVar; + } } $list_args[] = $this->parseArg($arg); } @@ -3566,20 +3572,24 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertToObject(NodeAbstract $object): string { $id = $this->parseIdentifier($object); - if ($this->isVarExpr($object) and $this->getVarType($id) === self::TYPE_OBJECT) { - return $id; - } - - if (isset($this->context->objectWrappers[$id])) { - return $this->context->objectWrappers[$id]; + if ($this->isVarExpr($object)) { + if ($this->getVarType($id) === self::TYPE_OBJECT) { + return $id; + } + if (isset($this->context->objectWrappers[$id])) { + return 'php_get_object_wrap(' . $this->context->objectWrappers[$id] . ', ' . $id . ')'; + } else { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_OBJECT); + $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . ' = ' . $id . ';'; + $this->context->objectWrappers[$id] = $tmpVar; + return $tmpVar; + } + } else { + $tmpVar = $this->genTmpVarName(); + $this->context->beforeStmtLines[] = $this->getIndent() . self::TYPE_OBJECT . ' ' . $tmpVar . ' = ' . $id . ';'; + return $tmpVar; } - - $tmpVar = $this->genTmpVarName(); - $this->addLocalVar($tmpVar, self::TYPE_OBJECT); - $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . ' = ' . $id . ';'; - $this->context->objectWrappers[$id] = $tmpVar; - - return $tmpVar; } protected function convertToRef(NodeAbstract $expr): string diff --git a/src/cpp/php_aot_helper.h b/src/cpp/php_aot_helper.h index eb849455..ad039bcc 100644 --- a/src/cpp/php_aot_helper.h +++ b/src/cpp/php_aot_helper.h @@ -23,3 +23,10 @@ extern void php_restore_scope(php::Scope &ori_scope); static inline auto php_get_create_object_fn(zend_class_entry *ce) { return ce->create_object ? ce->create_object : zend_objects_new; } + +static inline php::Object &php_get_object_wrap(php::Object &obj, php::Var &var) { + if (UNEXPECTED(obj.isNull())) { + obj = var; + } + return obj; +}