Files
Arnaud Le Blanc 2d359a40b7 [PFA 3/n] Support PFA in const exprs (#22785)
* Use a pointer to the declaring opline->lineno as unique addr, instead of the declaring opline itself

zend_partial_create() takes a 'zend_op* declaring_opline' parameter for the
purpose of building a cache key: the opline address is unique to this PFA as
long as it's in SHM.

However the declaring opline is not available when evaluating a PFA AST. Replace
the parameter by 'uint32_t* declaring_lineno'. Callers can pass
'&zend_op->lineno' or '&ast->lineno': Both are unique to the related PFA.

* zend_partial_create(): Remove the dependency on the declaring op_array

The declaring op_array is used for multiple purposes:
 * Generating a PFA name
 * Finding the filename
 * Finding whether op_array is cached, and therefore whether the PFA should be
   cached too

However it's not available when evaluating a PFA AST.

Remove the declaring_op_array argument, and pass the relevant information
directly:
 * Generate the PFA name at compile time, pass it as argument to zend_partial_create()
 * Pass the filename and a cacheable flag as argument to zend_partial_create()

* Support for PFA in constant expressions
2026-07-27 17:59:25 +02:00

46 lines
818 B
PHP

--TEST--
PFA in constexpr: sites
--FILE--
<?php
#[Attribute]
class A {
function __construct(public mixed $fn) {}
}
#[A(strlen(?))]
class C {
const CC = strlen(?);
#[A(strlen(?))]
function f($arg = strlen(?)) {
return $arg;
}
}
const CC = strlen(?);
echo "# Class const\n";
var_dump((C::CC)('hello'));
echo "# Const\n";
var_dump((CC)('hello'));
echo "# Class attr\n";
var_dump((new ReflectionClass(C::class)->getAttributes(A::class)[0]->newInstance()->fn)('hello'));
echo "# Method attr\n";
var_dump((new ReflectionMethod(C::class, 'f')->getAttributes(A::class)[0]->newInstance()->fn)('hello'));
echo "# Method default value\n";
var_dump((new C()->f())('hello'));
?>
--EXPECT--
# Class const
int(5)
# Const
int(5)
# Class attr
int(5)
# Method attr
int(5)
# Method default value
int(5)