On Tuesday, 28 May 2024 at 15:26, Derick Rethans <der...@php.net> wrote:
> On Mon, 27 May 2024, Ilija Tovilo wrote: > > > On Sun, May 26, 2024 at 11:47 PM Gina P. Banyard intern...@gpb.moe > > wrote: > > > > > On Wednesday, 8 May 2024 at 14:40, Gina P. Banyard > > > intern...@gpb.moe wrote: > > > > > > > I would like to formally propose my idea for exit() as a function > > > > brought up to the list on 2024-02-24 [1] with the following RFC: > > > > https://wiki.php.net/rfc/exit-as-function > > > > > > As there haven't been any comments for nearly two weeks, I'm > > > planning on opening the vote for the RFC on Tuesday. > > > Right now, I am not going to be in favour of this. Specfically because > the Backward Incompatible Changes don't list some of the backward > breaking changes, and no mitigations are provided. See below. > > I also don't see the benefit from doing this in the first place. > exit/die has always meant "bail straight out", without any function > semantics (from https://www.php.net/exit): > > exit — Output a message and terminate the current script > > exit is a language construct and it can be called without > parentheses if no status is passed. > > It's not that this a particularly new or novel behaviour. > > I saw somewhere else in the thread that the exit construct could already > throw a catchable exception. I consider that a bug. Considering the whole point of the RFC is to make it a function, I'm not sure why saying the current exit behaviour is not new or novel serves any purpose. Is catching a TypeError a bug? Is catching a ValueError a bug? Is catching any sort of engine Error a bug? Because this is effectively what you are saying, and if this is the case, we might as well just reverse the "Exceptions in the engine" RFC from 2014 [1] to make all those Errors fatal errors again which bail out immediately. This RFC makes exit() a function such that either it exits normally, or a TypeError is thrown if you feed it nonsense, consistently with all our type juggling semantics. Moreover, when exit() was changed to use an Exception internally there were various people in favour of being able to catch it, and have it run finally blocks (like other programming languages do) [2] It should also be noted exit() does not just bail out and do nothing else, any destructors will be run before the exiting, so one can still run userland code after it has been called [3] > I have just checked this for Xdebug, and you're definitely right with > that. With the removal of the ZEND_EXIT opcode, it can not now detect a > scope/function exit now. > > It also breaks my "do tasks on ZEND_EXIT" with the profiler. It is used > to always write the closing profiling footer to the files. Without me > being able to overload thati opcode, data would not be complete. > I even have two bugs (with tests) for this: > > - https://bugs.xdebug.org/68 > - https://bugs.xdebug.org/631 > > Xdebug has been overloading ZEND_EXIT for nearly 20 years now. AFAIK Opcodes are not part of any backwards compatibility guarantees. You could overwrite the function pointer of exit() at MINIT with a custom implementation. Alternatively, you could use the zend_is_unwind_exit() engine API to check if the exception that has been thrown is the one that corresponds to an exit call, this would work as of PHP 8.0. Finally, the one that makes more work for me, is to add a new observer API that indicates an exit() and hook into that one. > > > This could be re-added by checking for the never return type instead. > > > I can't quite see a way on how to do that? The EXIT is replaced by an > INIT_FCALL/DO_ICALL: > > 4 0 E > EXT_STMT > > 1 ECHO '55' > 5 2 EXT_STMT > - 3 > EXIT > > - 6 4* EXT_STMT > - 5* ECHO '675' > - 7 6* EXT_STMT > - 7* > RETURN null > > + 3 INIT_FCALL 'exit' > + 4 DO_ICALL > + 6 5 EXT_STMT > + 6 ECHO '675' > + 7 7 EXT_STMT > + 8 > RETURN null > > > The opcodes don't have direct access to the type mask structure as far > as I know. You can access the zend_function pointer from the opcode which has access to the type-mask info. Or, if required, the Zend/Optimizer/zend_func_infos.h file can be amended to include exit() and die() and expose the MAY_BE_NEVER return type. Best regards, Gina P. Banyard [1] https://wiki.php.net/rfc/engine_exceptions_for_php7 [2] https://externals.io/message/107497 [3] https://3v4l.org/gO9IK