Re: RFC idea: Block scoped variables with "let $x = expr"
| From: | tyson andre | Date: | Sun, 15 Mar 2020 22:57:25 +0000 |
| Subject: | Re: RFC idea: Block scoped variables with "let $x = expr" | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-109044@lists.php.net to get a copy of this message | ||
Hi Rowan,
> Do you know how the equivalent code works with function-scoped variables?
> As far as I can see, returning from a function will successfully call multiple
> destructors even if one of them throws an exception. Could exiting block
> scope use that same algorithm?
PHP literally frees all of the variables (even the ones which are definitely not reference counted)
without stopping if any of them throw an exception until everything is freed.
i_free_compiled_variables is called when exiting the function scope (e.g.
throw/return).
(the caller also decreases reference counts to the closure/$this, extra unexpected arguments, etc)
```
static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
{
zval *cv = EX_VAR_NUM(0);
int count = EX(func)->op_array.last_var;
while (EXPECTED(count != 0)) {
i_zval_ptr_dtor(cv);
cv++;
count--;
}
}
```
> Having the variable become inaccessible but not actually deallocated
> seems like it would cause a lot of confusion.
Good point about resources, I forgot about freeing being automatic.
I'm starting to lean towards deallocating.
If this was used within a try block or a top-level statement,
this could probably add a new opcode to free a variable that could throw
without checking for the exception,
and only the last opcode would need to throw the last exception.
(adding a new opcode to ensure deallocation of all variables without the equivalent of
a try/finally block for every additional let variable)
For global variables, there's already the problem in the engine that __destruct()
could itself create global variables of the same/different name.
- Tyson