* uri: Unify string creation in `php_uri_parser_rfc3986_scheme_read()`
* uri: Remove useless non-NULL assertions in uri_parser_rfc3986.c
The value of `uriparser_uri` is dereferenced *immediately* after the assertion,
making it redundant for both the human reader and the compiler. In case of the
normalized_uri, the pointer is trivially non-NULL, since it is referring to a
struct member at not-the-first position.
Generally speaking, unless something is checked for `NULL` one can assume it to
never be `NULL`.
* uri: Add `has_text_range()` helper to uri_parser_rfc3986.c
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#remove_disable_classes_ini_setting
This took longer to merge than expected but the initial motivation from 2 years ago still applied:
As described in the email to the PHP internals list [1] this feature is fundamentally broken and pointless.
Only internal classes can be disable which brings the following observation. On a minimal build of PHP, with only the mandatory extensions enabled, there are 148 classes/interfaces/traits defined. [2]
Other than the SPL ones (and even then), disabling any of these classes will cause issues within the engine.
Moreover, the SPL ones are not a security concern.
Therefore, any other class that can be disabled must come from an extension that can be disabled altogether. And "disabling" a class from an extension without disabling said extension will render it useless anyway.
If a hosting provided is concerned about an extension, then it should not enable it in the first place. Not break it ad hoc.
Considering the above, I cannot see how this functionality was ever useful.
This is in stark contrast to the disable_functions INI setting, which can be used to selectively remove functionality of an extension without breaking it overall.
What makes this setting particularly broken is that it does not unregister the class, it only overwrites the create CE handler to emit a warning and purge the properties and function hashtables. This leads to various use after free, segfaults, and broken expectations for the engine and extensions which define said classes. On top of that, it is possible to actually instantiate such a class (and even classes which actually disallow this like ext/imap) in userland, and pass it to function that are typed against said class without raising a TypeError. However, when trying to do anything with said object stuff is going to explode in countless ways.
[1] https://news-web.php.net/php.internals/120896
[2] https://gist.github.com/Girgias/63d55ba1e50b580412b004046daed02b
Follows-up 22e444c5c7 (GH-18670). There is currently no formula called
"iconv". [1][2]
```
$ brew install iconv
Warning: No available formula with the name "iconv". Did you mean icon or cconv?
```
There package is called "libiconv". [3]
Once installed, `./configure` still fails due to a discovery issue.
```
$ ./configure --enable-debug
…
checking for libiconv... no
configure: error: Please specify the install prefix of iconv with --with-iconv=<DIR>
```
In 2020, as part of the switch from Intel to ARM, Homebrew adopted /opt
as the standard location instead of /usr/local. [4][5]
Rather than complicating the README with a mandatory `--with-iconv`
path (or --without-iconv) for macOS users, improve the discovery
to support Homebrew's new location.
[1]: https://brew.sh/
[2]: https://github.com/Homebrew/homebrew-core/.
[3]: https://formulae.brew.sh/formula/libiconv
[4]: https://apple.stackexchange.com/a/437622/33762
[5]: https://docs.brew.sh/FAQ#why-is-the-default-installation-prefix-opthomebrew-on-apple-silicon
Introduce the TAILCALL VM, a more efficient variant of the CALL VM:
* Each opcode handler tailcalls the next opcode handler directly instead of
returning to the interpreter loop. This eliminates call and interpreter loop
overhead.
* Opcode handlers use the preserve_none calling convention to eliminate
register saving overhead.
* preserve_none uses non-volatile registers for its first arguments, so
execute_data and opline are usually kept in these registers and no code is
required to forward them to the next handlers.
Generated machine code is similar to a direct-threaded VM with register pinning,
like the HYBRID VM.
JIT+TAILCALL VM also benefits from this compared to JIT+CALL VM:
* JIT uses the registers of the execute_data and opline args as fixed regs,
eliminating the need to move them in prologue.
* Traces exit by tailcalling the next handler. No code is needed to forward
execute_data and opline.
* No register saving/restoring in epilogue/prologue.
The TAILCALL VM is used when the HYBRID VM is not supported, and the compiler
supports the musttail and preserve_none attributes: The HYBRID VM is used when
compiling with GCC, the TAILCALL VM when compiling with Clang>=19 on x86_64 or
aarch64, and the CALL VM otherwise.
This makes binaries built with Clang>=19 as fast as binaries built with GCC.
Before, these were considerably slower (by 2.8% to 44% depending on benchmark,
and by 5% to 77% before 76d7c616bb).
Closes GH-17849
Closes GH-18720
Since cbf67e4, the GC needs to find all WeakMaps referencing a weakly
referenced object. Doing so, it treats all ZEND_WEAKREF_TAG_MAP as WeakMap
instances.
However, a ZEND_WEAKREF_TAG_MAP reference may be a bare HashTable when
zend_weakrefs_hash_add() is used.
Introduce a new tag, ZEND_WEAKREF_TAG_BARE_HT, and use this tag when weakly
referencing an object from a bare HashTable. Ignore such references in GC.
Fixes GH-19543
Closes GH-19544
Co-authored-by: Tim Düsterhus <tim@tideways-gmbh.com>