Some code paths were checking this manually, but we can turn this
into a general assertion to avoid surprises (functions returning
failure without throwing).
exit() is now internally implemented by throwing an exception,
performing a normal stack unwind and a clean shutdown. This ensures
that no persistent resource leaks occur.
The exception is internal, cannot be caught and does not result in
the execution of finally blocks. This may be relaxed in the future.
Closes GH-5768.
I decided to null out EG(exception) early here, which means only
the exception from the dtor / ref assign is preserved, and the
previous exception is not chained in. This is more robust, and
I don't think this situation is common enough to be bothered about
the precise behavior.
We have a bunch of APIs for getting type names and it's sometimes
hard to keep them apart ... make it clear that this is the one
you definitely do not want to use.
The 'int dummy' parameter to this function makes it appear that it was intended as a
signal handler, but it is not being used as such. So remove the redundant parameter.
This has the minor benefit of avoiding loading the address of the
jump table when the expression for the switch isn't a string/long.
gcc doesn't seem to optimize that.
The previous function body is the original implementation: ad8652818a
```
// Before: 0.267s, after: 0.265s
function test_switch($x) {
for ($i = 0; $i < 10000000; $i++) {
switch ($x) {
case 'a':
case 'b':
echo "i=$i\n";
}
}
}
test_switch(null);
```
Closes GH-5419
Don't check all the remaining arguments after one check failed.
I don't think this makes an observable behavior difference,
because we already suppress duplicate exceptions in argument
type error reporting.
This reverts commit bb43a3822e.
After thinking about this a bit more, this is now going to be
a complete solution for the "readonly properties" case, for example:
unset($foo->readOnly->bar);
should also be legal and
$foo->readOnly['bar'] = 42;
should also be legal if $foo->readOnly is not an array but an
ArrayAccess object.
I think it may be better to distinguish better on the BP_VAR flag
level. Reverting for now.
$a->b->c = 'd';
is now compiled the same way as
$b = $a->b;
$b->c = 'd';
That is, we perform a read fetch on $a->b, rather than a write
fetch.
This is possible, because PHP 8 removed auto-vivification support
for objects, so $a->b->c = 'd' may no longer modify $a->b proper
(i.e. not counting interior mutability of the object).
Closes GH-5250.
* PHP-7.4:
Check asserts early
identation fix
Call global code of preloaded script in global context
Avoid "Anonymous class wasn't preloaded" error by lazely loading of not preloaded part of a preloaded script
Unlink the current stack frame before freeing CVs or extra args.
This means it will no longer show up in back traces that are
generated during CV destruction.
We already did this prior to destructing the object/closure,
presumably for the same reason.
Followup for d74d3922ce
Attempting to require a file with (unset) casts results in an E_COMPILE_ERROR
that can't be caught or handled by set_exception_handler/set_error_handler.
Also remove the (bool) cast, because the ZEND_BOOL opcode handles that.
Remove inference that array -> object cast can throw.
It was added in 2a286ad599 - I don't know how creating an stdClass would throw.
(numeric keys, references, etc. don't cause it to throw)
Closes GH-5042
Add a specialized opcode handler to use for `===`/`!==` when:
1. At least one side is a $cv, and the other is a $cv or CONST
(avoids the need to free operands)
2. Neither operand can be undefined or a reference
(avoids the need for error handling and dereferencing)
```
// Elapsed time decreased from 0.275 seconds to 0.243 seconds in combination
// with PR #4982
function count_same(array $values) {
$same = 0;
foreach ($values as $x) {
foreach ($values as $y) {
if ($y === $x) {
$same++;
}
}
}
return $same;
}
$values = range(0, 5000);
$values[] = new stdClass();
$values[] = null;
$values[] = 3;
$start = microtime(true);
$total = count_same($values);
```