[RFC] Make throw statement an expression#5279
[RFC] Make throw statement an expression#5279iluuu1994 wants to merge 1 commit into
Conversation
|
Looks reasonable at first glance, though exact precedence may need some more thought. |
|
@nikic Thanks for your initial assessment! I wasn't sure about precedence either.
Of course, there are many other things to consider. |
f26a4bd to
501a9e6
Compare
|
As the main authors of the code in question I'm taking the liberty of consulting the two of you. The following snippet: var_dump(
throw new Exception("exception 1"),
throw new Exception("exception 2")
);Caused a SEGFAULT in the zend_call_graph.c: because |
|
@iluuu1994 Also reproduces with so we should fix this independently. |
|
@iluuu1994 Should be fixed with 34f1266 / 2e8db5d. I don't want to put in a fake value, we have few enough uses that we can just check for NULL. |
|
@nikic Ok, I'll rebase the branch and check if it works. |
a95da8a to
37e4224
Compare
|
Looks good, thanks @nikic! |
|
@iluuu1994 Take a look at https://bugs.php.net/bug.php?id=67184 :) |
|
@carusogabriel I'm planning to start the voting on this RFC next week. If it passes I can make another RFC for the remaining keywords 🙂 |
|
It seems OPcache (the optimizer?) needs to be adjusted. Currently, <?php
try {
throw new Exception(throw new Exception('foo'));
} catch (Exception $ex) {}leaks memory. |
|
Thanks @cmb69. I tracked it down to this: (rebased onto master) I'll see if I can find out what's going on tomorrow. |
|
Is the intention behind removing the |
|
Expressions evaluate to some value while statements do not.
https://en.wikipedia.org/wiki/Bottom_type The main reason for doing so is that |
|
@iluuu1994 thanks for explaining. |
|
Here are the unoptimized opcodes: vs the optimized ones: So it looks like it removes everything between the first |
|
It looks like var_dump(exit());Unoptimized: Optimized: The This happens in the CFG optimization pass (pass 5). |
|
As discussed in #5358 the memory leak is related to the live ranges, not |
EDIT: Never mind, my comments were already mentioned by others in the review comments for 5358 already> It looks like `exit` suffers from the same problem.If valgrind doesn't warn about a memory leak, it's probably not a severe issue - optimizing bad php code like Also note that INIT_FCALL_BY_NAME would throw if the function was undefined, but INIT_FCALL should almost always have a defined function A part of the problem is that the memory for V1 is getting reused, so the first incomplete object is lost track of. I don't know why opcache thought it was safe to reuse that temporary value - it might be specific to I see that
Before rebasing this branch
|
37e4224 to
0796c09
Compare
0796c09 to
66523d5
Compare
nikic
left a comment
There was a problem hiding this comment.
I'll go ahead and merge this, so we have a possibility to test expression control flow issues in-tree. While exit has the same basic problem, it's use of bailout results in leaks being suppressed, so it's not a good test target.
|
Thanks @nikic. I'll try to get more familiar with the whole memory management over the next couple of days. I doubt I can come up with a good solution though if you can't. 😆 Should I move the RFC to "Implemented" or wait until we've fully resolved these issues? |
|
Shall we close https://bugs.php.net/bug.php?id=67184? I believe that one is now fixed, right? |
|
Good catch, @carusogabriel. I've closed that ticket. |
|
@iluuu1994 I started some work on this in master...nikic:throw-leak. It's ugly, but I think it will work. And yes, feel free to move to the RFC to Implemented. |
|
Big thanks @nikic for the help! |
Implementation for https://wiki.php.net/rfc/throw_expression.
Inspired by this tweet. Of course, this will require an RFC but I wanted to ask for opinions beforehand since this is my first contribution to the php interpreter.