Hi internals,
https://wiki.php.net/rfc/calls_in_constant_expressions has hit some roadblocks
in the implementation shortly after the last email.
I've been blocked on how to resolve them in the implementation in a way I'm
certain would work.
I had assumed the calling scope wouldn't have the below issues when I started
working on this RFC, but was mistaken.
- The helper method the C code uses, `zend_call_function()`, will always act
as though `strict_types=0`. I'd consider this a blocker for
`declare(strict_types=1); const X = intdiv("123", 2);`. (Internally,
zend_call_function adds a fake call frame without a function, similar to what
__get, invocations of error handlers, etc do, and that call frame makes the
parameter parsing helper macros of the invoked function treat it like
strict_types=0)
It may also be desirable to specify calls in constants always work like
strict_types=1, to avoid issues such as `strpos($float, '.')` being
locale-dependent)
- Getting the class scope *of the constant declaration* to work properly with
`callable` (e.g. `public $x = array_map('self::helperMethod', VALUES);`).
This isn't an issue with only a whitelist.
- Solving the above two issues while continuing to throw for func_get_args(),
get_defined_vars(), etc.
get_defined_vars() would throw for dynamic calls, but the above approaches
would act like
Currently, my best ideas to fix some of the 3 issues were:
- Create a fake zend_function placeholder in C with a placeholder name and add
it to the internal stack of calls (EG(current_execute_data)).
Currently, though, it's only possible to set strict_types=1 for user-defined
functions.
- Create an actual closure when compiling the code, which would be evaluated
the same way as `public $x = (static function() { return
array_map('self::helperMethod', VALUES); })()`
(i.e. a closure without any `use` variables. The )
This would solve it, but the performance would be unexpectedly worse than
expected, and that would interfere with optimizations.
- Create an alternative to zend_call_function, but that would duplicate code
and be error prone.
I'm not familiar enough with XDebug, NewRelic, uopz, and other replacements
of zend_vm_execute to know if those would be able to support that,
or if there would be even more issues I haven't thought up yet that would
prevent .
Second, I realize it doesn't make much sense to restrain the constant
expressions for parameter defaults and class constants in the same way.
The RFC was coherent proposing allowing any function call in 5 places, but less
coherent proposing a whitelist of functions, even where those restrictions
weren't necessary.
- It may be desirable to support many extra expression types in parameter
defaults and static property defaults
(`function myFunc(object $x = new DefaultObject()) {}`)
but still limit class constants to the proposed whitelist of functions.
Third, I was considering a straw poll for this,
but don't know what's required to set one up.
It also didn't make sense to me without a solution to the roadblocks.
1. Desired expressions in param defaults (No change/Whitelisted functions/Any
function/Any method + new X()+others)
2. ... in static property defaults
3. ... in static variable defaults
4. ... in class constant values
5. ... in const X = ...
Thanks,
- Tyson
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php