Update gen_stubs.php to generate C enums from internal enums, when the stub is annotated with @generate-c-enums. Enum values can be compared to the result of zend_enum_fetch_case_id(zend_object*).
The generated enums are added to separate files named {$extensionName}_decl.h, so that it's possible to include these from anywhere. _arginfo.h files would generate warnings if we tried to include them in a compilation unit that doesn't call the register_{$class} functions, for instance.
Introduce Z_PARAM_ENUM().
* Make ZEND_AST_CONST_ENUM_INIT a 4-children node
* Store enum case id in ZEND_AST_CONST_ENUM_INIT
* Store enum case id in instance
* Expose enum case_id internally
* Generate C enum for internal enums
* Introduce Z_PARAM_ENUM()
* Port extensions
The aim of this PR is twofold:
- Reduce the number of highly similar TMP|VAR handlers
- Avoid ZVAL_DEREF in most of these cases
This is achieved by guaranteeing that all zend_compile_expr() calls, as well as
all other compile calls with BP_VAR_{R,IS}, will result in a TMP variable. This
implies that the result will not contain an IS_INDIRECT or IS_REFERENCE value,
which was mostly already the case, with two exceptions:
- Calls to return-by-reference functions. Because return-by-reference functions
are quite rare, this is solved by delegating the DEREF to the RETURN_BY_REF
handler, which will examine the stack to check whether the caller expects a
VAR or TMP to understand whether the DEREF is needed. Internal functions will
also need to adjust by calling the zend_return_unwrap_ref() function.
- By-reference assignments, including both $a = &$b, as well as $a = [&$b]. When
the result of these expressions is used in a BP_VAR_R context, the reference
is unwrapped via a ZEND_QM_ASSIGN opcode beforehand. This is exceptionally
rare.
Closes GH-20628
* zend_compile: Fix handling of PFA syntax in array_map() optimization
PFA is not implemented and the syntax is rejected at compile-time, thus it was
assumed the assertion would be unreachable. However the check for PFA syntax
happens after compiling special functions, making it reachable. Fix this by
gracefully returning FAILURE which will then correctly emit the error during
the compilation of the normal call.
Fixesphp/php-src#20991.
* zend_compile: Fix array_map() optimization for dynamic function names
Fixesphp/php-src#20990.
* zend_compile: Adjust array_map() optimization after review feedback
RFC: https://wiki.php.net/rfc/partial_function_application_v2
For FCCs, the parser generates a normal function call AST node, the but argument
list is a ZEND_AST_CALLABLE_CONVERT / zend_ast_fcc node.
We extend this for PFAs so that zend_ast_fcc can represent arguments.
* Support PFA syntax in grammar
* Update zend_ast_fcc so that arguments can be represented
* Support serialization of zend_ast_fcc arguments in SHM / file cache
* Introduce zend_ast_arg_list_add(): Same as zend_ast_list_add(), but wraps the
list in a ZEND_AST_CALLABLE_CONVERT when adding any placeholder argument.
Technically the arg list wrapping is not required, but it results in simpler
code later as it will be very convenient in the compiler (determines whether a
function calls is a PFA/FCC), and for PFA-in-const-expr support. It also allows
to unify FCCs and PFAs in the grammar.
Closes GH-20717.
As the comment suggests, the return value of frameless calls is rarely not used.
When it isn't used (and isn't refcounted) the FREE is already elided by the
optimizer.
Closes GH-20819
The arg_info member of zend_function is now always a zend_arg_info*. Before,
it was a zend_internal_arg_info* on internal functions, unless the
ZEND_ACC_USER_ARG_INFO flag was set.
Closes GH-19022
Previously, the assignment op line was only emitted when one of the other flags
allowed for promoted properties (visibility, set visibility, or readonly) was
also used, or when the property had hooks. The property was still added to the
class, but the magical assignment `$this->prop = $prop` was missing. Add that
assignment even when no visibility is explicitly specified, and a test to
confirm the fix.
* zend_compile: Add `is_func_accessible()` helper
* zend_compile: Use `zend_set_class_name_op1()` in `zend_compile_new()`
* zend_compile: Optimize arguments for ZEND_NEW
Apply the optimization for static method calls to `new` calls, since `new` is
effectively a static method for all intents and purposes.
For:
<?php
final class MyClass
{
private function __construct(
private \Random\Engine $foo,
private int $bar = 0,
) {}
public static function new(int $bar): self
{
$engine = new \Random\Engine\Xoshiro256StarStar(seed: 123);
return new self(foo: $engine, bar: $bar);
}
}
for ($i = 0; $i < 3_000_000; $i++) {
MyClass::new($i);
}
This is ~1.13 faster for a gcc 13.3 release build on a Intel(R) Core(TM)
i7-1365U.
Benchmark 1: /tmp/bench/php.old /tmp/bench/test6.php
Time (mean ± σ): 409.5 ms ± 1.9 ms [User: 406.6 ms, System: 2.2 ms]
Range (min … max): 407.4 ms … 414.0 ms 10 runs
Benchmark 2: /tmp/bench/php.new /tmp/bench/test6.php
Time (mean ± σ): 360.9 ms ± 1.7 ms [User: 358.5 ms, System: 2.2 ms]
Range (min … max): 359.2 ms … 365.0 ms 10 runs
Summary
/tmp/bench/php.new /tmp/bench/test6.php ran
1.13 ± 0.01 times faster than /tmp/bench/php.old /tmp/bench/test6.php
Note that ZEND_COPY_TMP isn't even valid for CONSTs, and we would need
to add a ref even if it were, so just add special handling instead to
simplify it.
* PHP-8.5:
PHP 8.5 | UPGRADING: fix entry about new grapheme $locale parameter (#20239)
uri: Make uri_parser_rfc3986.h usable for external extensions (#20173)
Fix missing deprecation message for default case statement followed by semicolon (#20172)
* tree-wide: Replace `zval_is_true()` by `zend_is_true()`
The former is a direct alias of the latter which is much more often used.
* zend_operators: Remove `zval_is_true()`
Happens due to changes in 28fd7597ba where the opline opcode may be
accessed after the opcode array has been reallocated.
To solve this we store the opcode in a temporary variable.
This cache is implemented in two levels: A EG(callable_convert_cache) global
that maps zend_function pointers to a shared callable instance, and a
CALLABLE_CONVERT cache slot to remember the result of the hash table lookup.
Fixes GH-19754
Closes GH-19863
Avoid returning early in this function, as other checks might still be needed to
verify whether the given function can procude an error.
Fixes oss-fuzz #447521098
Closes GH-19972
In CGI, php_auto_globals_create_server() (i.e. auto_global_callback() here)
initializes $_ENV to reuse for $_SERVER. However, because $_SERVER is
constructed first, we have not yet initialized auto_global->armed of the $_ENV
global. Split the loop into initialization and constructor phases.
Closes GH-19870