fix(generator): 修复代码生成器中的引用传递问题

- 在函数、参数、常量和属性的代码生成中添加refval包装器
- 确保use引用变量正确传递给代码生成函数
- 解决闭包中通过回调使用引用捕获的功能问题
- 添加测试用例验证闭包引用捕获的正确性
pull/4/head
韩天峰 2 months ago
parent b13fdc60fa
commit 9c5bf37b6f
  1. 10
      src/gen_stub.php
  2. 74
      tests/aot/closure/closure-use-reference-callback.phpt

@ -5555,7 +5555,7 @@ function generateFunctionAttributeInitialization(iterable $funcInfos, array $all
"func_" . $funcInfo->name->getNameForAttributes() . "_$key",
$allConstInfos,
$phpVersionIdMinimumCompatibility,
$useDeclared
refval($useDeclared)
);
}
@ -5566,7 +5566,7 @@ function generateFunctionAttributeInitialization(iterable $funcInfos, array $all
"func_{$funcInfo->name->getNameForAttributes()}_arg{$index}_$key",
$allConstInfos,
$phpVersionIdMinimumCompatibility,
$useDeclared
refval($useDeclared)
);
}
}
@ -5627,7 +5627,7 @@ function generateGlobalConstantAttributeInitialization(
$constVarName . "_$key",
$allConstInfos,
PHP_85_VERSION_ID,
$useDeclared
refval($useDeclared)
);
}
@ -5675,7 +5675,7 @@ function generateConstantAttributeInitialization(
"const_" . $constInfo->name->getDeclarationName() . "_$key",
$allConstInfos,
$phpVersionIdMinimumCompatibility,
$useDeclared
refval($useDeclared)
);
}
@ -5705,7 +5705,7 @@ function generatePropertyAttributeInitialization(
"property_" . $propertyInfo->name->getDeclarationName() . "_" . $key,
$allConstInfos,
$phpVersionIdMinimumCompatibility,
$declaredStrings
refval($declaredStrings)
);
}
}

@ -0,0 +1,74 @@
--TEST--
Closure use reference capture through callbacks
--FILE--
<?php
function apply_items(array $items, callable $cb): string
{
$out = '';
foreach ($items as $item) {
$result = $cb($item);
if ($result !== null) {
$out .= $result;
}
}
return $out;
}
function main(): void
{
$errors = [];
array_map(function ($value) use (&$errors) {
if ($value % 2 === 0) {
$errors[] = "even:$value";
}
return null;
}, [1, 2, 3, 4]);
var_dump($errors);
$generated = [];
$code = apply_items([1, 2, 3], function ($value) use (&$generated) {
$generated[] = $value * 10;
return "[$value]";
});
var_dump($code);
var_dump($generated);
$declaredStrings = [];
$emit = function (string $name) use (&$declaredStrings): string {
if (isset($declaredStrings[$name])) {
return $declaredStrings[$name];
}
$declaredStrings[$name] = 's_' . count($declaredStrings);
return $declaredStrings[$name];
};
var_dump($emit('alpha'));
var_dump($emit('beta'));
var_dump($emit('alpha'));
var_dump($declaredStrings);
}
?>
--EXPECT--
array(2) {
[0]=>
string(6) "even:2"
[1]=>
string(6) "even:4"
}
string(9) "[1][2][3]"
array(3) {
[0]=>
int(10)
[1]=>
int(20)
[2]=>
int(30)
}
string(3) "s_0"
string(3) "s_1"
string(3) "s_0"
array(2) {
["alpha"]=>
string(3) "s_0"
["beta"]=>
string(3) "s_1"
}
Loading…
Cancel
Save