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

Reply via email to