Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Convert exit (and die) from language constructs to functions #13483

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Feb 23, 2024

The main motivation here is to have the same type juggling semantics as every other function in PHP.
Also, we don't need to have an opcode any more for it.

RFC: https://wiki.php.net/rfc/exit-as-function

Comment on lines 5015 to 5021
if (UNEXPECTED(
zend_string_equals_literal_ci(Z_STR_P(key), "exit")
|| zend_string_equals_literal_ci(Z_STR_P(key), "die")
)) {
zend_throw_unwind_exit();
return FAILURE;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we achieve similar results with by de-sugaring exit; to a function call at the AST level? (e.g. zend_compile_const() can replace the AST with a function call AST and delegate to zend_compile_call()). This would remove the need for special cases at runtime, and also unify the behavior of exit; and exit(); (wrt to disable_functions).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Special-casing exit/die constant access doesn't sound like a cleaner solution than what we have now. Keeping them in the lexer/parser also keeps BC for AST-based tools.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and it has side effects like defined(), constant() calls etc.

We may opt to special-case only statement-level "exit" and "die" constant fetches directly (i.e. handle in zend_compile_stmt, in the branch for constants).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's actually a smarter way of doing it!

I'll see if I can implement this, as I still struggle with the compiler part.

Copy link
Member

@iluuu1994 iluuu1994 Feb 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may opt to special-case only statement-level "exit" and "die" constant fetches directly (i.e. handle in zend_compile_stmt, in the branch for constants).

I would prefer keeping parser support, as otherwise PHPStan and the likes need to adjust. I don't think there's a reason to break those. Edit: I guess lexer would be sufficient, as almost all of these tools use PHPParser, which defines its own AST. Still, I'd prefer letting the parser handle this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to suggest something similar, because exit; not actually calling the function but just throwing that unwind exception probably leads to observable behavioral differences in debuggers dependent on whether the user wrote exit; or exit();, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should constrain ourselves with respect to phpstan etc.; there are worse BC breaks to be had.
I think the lexer, parser and opcodes are aside from any compatibilty guarantees.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ondrejmirtes has told me that this shouldn't be an issue if PHPParser still works, I'm asking @dseguy if this would affect Exakat or not.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@exakat will need an adaptation, at the parser level. That is not an issue.

@Girgias Girgias force-pushed the exit-as-function branch 2 times, most recently from 0549f75 to 89aaa8f Compare May 1, 2024 15:07
Zend/zend_compile.c Outdated Show resolved Hide resolved
@Girgias Girgias marked this pull request as ready for review May 7, 2024 18:27
@dstogov
Copy link
Member

dstogov commented May 8, 2024

Where is the RFC?

Removing ability to use die and exit without brackets, may effect a lot of PHP users.
I wouldn't accept this into PHP-8.*.

Please consider the possibility of adding die/exit functions without removing opcodes.
(This is just a quick idea. May be it doesn't make sense)

@iluuu1994
Copy link
Member

@dstogov See zend_compile.c, the constants are turned into function calls.

That said, I'm also a bit sceptical about the proposed benefits. I think an RFC, or at least a list on the mailing list explaining the rationale would be reasonable.

@dstogov
Copy link
Member

dstogov commented May 8, 2024

I think an RFC, or at least a list on the mailing list explaining the rationale would be reasonable.

The PR name contains [RFC], but I didn't find the text.

@dstogov
Copy link
Member

dstogov commented May 8, 2024

@dstogov See zend_compile.c, the constants are turned into function calls.

Nice hack :), but it needs to be verified (constants may be used in places where calls are not allowed).

@Girgias
Copy link
Member Author

Girgias commented May 8, 2024

The RFC is now live: https://wiki.php.net/rfc/exit-as-function and I have sent an email to internals.

I'm still somewhat ill so I didn't manage to post it yesterday.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants