perf(compiler): optimize multi-return tuple assignment with move semantics - Replace temporary Var construction with direct tuple element assignment - Implement std::move for final local variable uses to avoid unnecessary copies - Track remaining variable uses to determine when to apply move semantics - Preserve PHP value-assignment semantics for references and indirect zvals - Add comprehensive test coverage for tuple multi-return scenarios - Include tests for repeated values, references, globals, and static variables ```pull/20/head
parent
fa7e2cf7c1
commit
aba8d9194d
4 changed files with 179 additions and 3 deletions
@ -0,0 +1,132 @@ |
||||
--TEST-- |
||||
Tuple multi-return production safely consumes final local uses |
||||
--FILE-- |
||||
<?php |
||||
function multi_return_owned_values(): array |
||||
{ |
||||
$text = 'owned'; |
||||
$array = [1, 2]; |
||||
$object = new stdClass(); |
||||
$object->value = 3; |
||||
return [$text, $array, $object]; |
||||
} |
||||
|
||||
function multi_return_repeated_value(): array |
||||
{ |
||||
$value = ['repeated']; |
||||
return [$value, $value]; |
||||
} |
||||
|
||||
function multi_return_reference_value(&$value): array |
||||
{ |
||||
$alias =& $value; |
||||
return [$alias, $alias]; |
||||
} |
||||
|
||||
function multi_return_global_value(): array |
||||
{ |
||||
global $multiReturnGlobal; |
||||
return [$multiReturnGlobal, $multiReturnGlobal]; |
||||
} |
||||
|
||||
function multi_return_static_value(): array |
||||
{ |
||||
static $value = ['static']; |
||||
return [$value, $value]; |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
global $multiReturnGlobal; |
||||
$multiReturnGlobal = ['global']; |
||||
|
||||
[$text, $array, $object] = multi_return_owned_values(); |
||||
var_dump($text, $array, $object->value); |
||||
|
||||
[$first, $second] = multi_return_repeated_value(); |
||||
$first[] = 'changed'; |
||||
var_dump($first, $second); |
||||
|
||||
$source = 'reference'; |
||||
[$referenceFirst, $referenceSecond] = multi_return_reference_value($source); |
||||
$referenceFirst = 'changed'; |
||||
var_dump($source, $referenceFirst, $referenceSecond); |
||||
|
||||
$compatibleArray = multi_return_reference_value($source); |
||||
$compatibleArray[0] = 'array changed'; |
||||
var_dump($source, $compatibleArray); |
||||
|
||||
[$globalFirst, $globalSecond] = multi_return_global_value(); |
||||
$globalFirst[] = 'changed'; |
||||
var_dump($multiReturnGlobal, $globalFirst, $globalSecond); |
||||
|
||||
[$staticFirst, $staticSecond] = multi_return_static_value(); |
||||
$staticFirst[] = 'changed'; |
||||
var_dump($staticFirst, $staticSecond, multi_return_static_value()); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(5) "owned" |
||||
array(2) { |
||||
[0]=> |
||||
int(1) |
||||
[1]=> |
||||
int(2) |
||||
} |
||||
int(3) |
||||
array(2) { |
||||
[0]=> |
||||
string(8) "repeated" |
||||
[1]=> |
||||
string(7) "changed" |
||||
} |
||||
array(1) { |
||||
[0]=> |
||||
string(8) "repeated" |
||||
} |
||||
string(9) "reference" |
||||
string(7) "changed" |
||||
string(9) "reference" |
||||
string(9) "reference" |
||||
array(2) { |
||||
[0]=> |
||||
string(13) "array changed" |
||||
[1]=> |
||||
string(9) "reference" |
||||
} |
||||
array(1) { |
||||
[0]=> |
||||
string(6) "global" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(6) "global" |
||||
[1]=> |
||||
string(7) "changed" |
||||
} |
||||
array(1) { |
||||
[0]=> |
||||
string(6) "global" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(6) "static" |
||||
[1]=> |
||||
string(7) "changed" |
||||
} |
||||
array(1) { |
||||
[0]=> |
||||
string(6) "static" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
array(1) { |
||||
[0]=> |
||||
string(6) "static" |
||||
} |
||||
[1]=> |
||||
array(1) { |
||||
[0]=> |
||||
string(6) "static" |
||||
} |
||||
} |
||||
Loading…
Reference in new issue