We no longer protect GC during the destroy phase, so we need to
deal with buffer reallocation.
Note that the implementation of spl_SplObjectStorage_free_storage
will call the destructor of SplObjectStorage, and free the instance properties,
which I think is what caused the root buffer to be reallocated.
(`current` is a pointer for an index within the root buffer?)
This fixes bug #78811 for me.
Closes GH-4935
We no longer protect GC during the destroy phase, so we need to
deal with buffer reallocation.
Note that the implementation of spl_SplObjectStorage_free_storage
will call the destructor of SplObjectStorage, and free the instance properties,
which I think is what caused the root buffer to be reallocated.
(`current` is a pointer for an index within the root buffer?)
This fixes bug #78811 for me.
Closes GH-4935
In the case where there are still references to an array being iterated
over when the iterator is freed (or the array is not reference counted):
- There's need to save the opline.
- There's no need to check for exceptions.
```
// Before: 0.404 seconds
// After: 0.362 seconds
// loop_iter_empty(1000, 5000);
function loop_iter_empty(int $a, int $b) {
$values = array_fill(0, $b, []);
$total = 0;
for ($i = 0; $i < $b; $i++) {
foreach ($values as $v) {
foreach ($v as $x) {
$total += $x;
}
}
}
return $total;
}
```
And `$x = !$x`
Noticed while working on GH-4912
The included test would not emit undefined variable errors in php 8.0
with opcache enabled. The command used:
```
php -d zend_extension=opcache.so --no-php-ini -d error_reporting=E_ALL \
-d opcache.file_cache= -d opcache.enable_cli=1 test.php
```
Using this requires care! The zpp implementation for this union
must be consistent with the arginfo implementation!
Apart from array|object, this is probably only the case for
int|float right now.
Do this by reusing the implementation used for `==`
when both arguments are ints (IS_LONG) or both are floats (IS_DOUBLE)
```php
// Before: nestedloop_ni took 0.442 seconds
// After: nestedloop_ni takes 0.401 seconds (same as nestedloop_ne)
function nestedloop_ni(int $k) {
$x = 0;
for ($i=0; $i < 50000000; $i++) {
if ($i === $k) {
$x++;
}
}
print "$x\n";
}
function nestedloop_ne(int $k) {
$x = 0;
for ($i=0; $i < 50000000; $i++) {
if ($i == $k) {
$x++;
}
}
print "$x\n";
}
```
Optimizations such as specializations for is_resource were first added in
dfb4f6b38d9efedafab7d2d98b9333715561256
I don't see any mention of is_scalar (and optimizing it) in the commit history,
or in prior PRs on github, or searching for is_scalar in externals.io
Fixes a bug introduced in 4008704f62
The trailing comma is followed by `)` when the varargs list
is empty in the macro, which is a syntax error in C
This fixes compilation of code such as the following
PHP_FUNCTION(get_metadata) {
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "") == FAILURE) {
return;
}
Closes GH-4896.
According to RFC: https://wiki.php.net/rfc/union_types_v2
The type representation now makes use of both the pointer payload
and the type mask at the same time. Additionall, zend_type_list is
introduced as a new kind of pointer payload, which is used to store
multiple class types. Each of the class types is a tagged pointer,
which may be either a class name or class entry. The latter is only
used for typed properties, while arguments/returns will instead use
cache slots. A type list can contain a mix of both names and CEs at
the same time, as not all classes may be resolvable.
One thing this is missing is support for union types in arginfo
and stubs, which I want to handle separately.
I've also dropped the special object code from the JIT implementation
for now -- I plan to add this back in a different form at a later time.
For now I did not want to include non-trivial JIT changes together
with large functional changes.
Another possible piece of follow-up work is to implement "iterable"
as an internal alias for "array|Traversable". I believe this will
eliminate quite a few special-cases that had to be implemented.
Closes GH-4838.
We now store the pointer payload and the type mask separately. This
is in preparation for union types, where we will be using both at
the same time.
To avoid increasing the size of arginfo structures, the
pass_by_reference and is_variadic fields are now stored as part of
the type_mask (8-bit are reserved for custom use).
Different types of pointer payloads are distinguished based on bits
in the type_mask.
We have a number of "types" like integer which are not actually
supported as builtin types -- instead they are silently interpreted
as class types.
I've seen this cause confusion a few types already. This change adds
a warning in this case. In the unlikely case that someone legitimately
wants to type against an integer class, the warning can be suppressed
by writing \integer or "use integer", or using Integer (this warning
will only trigger for lowercase spellings).
Closes GH-4815.
* Change a number of "resource used as offset" notices to warnings,
which were previously missed.
* Throw the "resource used as offset" warning for isset() as well.
* Make array_key_exists() behavior with regard to different key
types consistent with isset() and normal array accesses. All key
types now use the usual coercions and array/object keys throw
TypeError.
Closes GH-4887.
This reverts commit edccf32f7f.
This was reported to cause issues for as yet unknown reasons in
bug #78769. As this was intended as code cleanup, revert this from
7.4 at least. May reapply it to master later.
Since `zend_parse_parameters()` throws now, there is no reason to
explicitly call `zend_parse_parameters_throw()` anymore, and since both
have actually the same implementation, we redefine the latter as macro.
These were checking whether the instruction set is supported by
the host CPU, however they were only used to condition on whether
this instruction set is targeted at all. It would still use dynamic
dispatch (e.g. based on ifunc resolvers) to select the actual
implementation. Whether the target is guaranteed to support the
instruction set without dispatch is determined based on pre-defined
macros like __SSE2__.
This removes the configure-time builtin cpu checks to remove
confusion. Additionally this allows targeting an architecture that
is newer than the host architecture.