Commit graph

2902 commits

Author SHA1 Message Date
Tim Düsterhus
551038bb16
zend_compile: Fully remove ZEND_DIM_ALTERNATIVE_SYNTAX (#14974)
This flag is longer set since the merge of property hooks in
780a8280d2. This patch removes it completely,
because the corresponding error messages are unreachable.
2024-07-16 16:27:46 +02:00
Ilija Tovilo
780a8280d2
[RFC] Property hooks (#13455)
RFC: https://wiki.php.net/rfc/property-hooks

Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
2024-07-14 11:55:03 +02:00
Arnaud Le Blanc
0bd260218b
Fix stack limit on ASAN/MSAN (#14771)
Increase the reserved stack size in ASAN builds, as instrumentation use more stack.
Increase the max allowed stack size in some tests, and enable these tests under ASAN.
Use __builtin_frame_address(0), instead of some stack variable, when we need a stack address, as ASAN may store local variables outside of the real stack.
2024-07-03 19:23:34 +02:00
Benjamin Eberlei
72c874691b
RFC: Add #[\Deprecated] Attribute (#11293)
see https://wiki.php.net/rfc/deprecated_attribute

Co-authored-by: Tim Düsterhus <tim@tideways-gmbh.com>
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
2024-07-02 09:44:25 +02:00
Niels Dossche
c97885b3cc
Merge branch 'PHP-8.3'
* PHP-8.3:
  Factor out common check for short-circuited ast
  Fix OSS-Fuzz #69765: Yield reference to nullsafe chain
2024-06-30 13:38:58 +02:00
Niels Dossche
015b5195ae
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Factor out common check for short-circuited ast
  Fix OSS-Fuzz #69765: Yield reference to nullsafe chain
2024-06-30 13:38:44 +02:00
Niels Dossche
8fd095669a
Factor out common check for short-circuited ast 2024-06-30 13:38:14 +02:00
Niels Dossche
d568337680
Fix OSS-Fuzz #69765: Yield reference to nullsafe chain
You cannot return or yield a reference to a nullsafe chain. This was
checked already in zend_compile_return but not yet in
zend_compile_yield.

Closes GH-14716.
2024-06-30 13:38:06 +02:00
Derick Rethans
9b5c15ba98 Remove superfluous whitespace 2024-06-26 08:06:41 -05:00
Derick Rethans
df7d304b62 Emit opcode for frameless functions at line number where the function call starts 2024-06-26 08:06:41 -05:00
Tim Düsterhus
2c5ed50d5c
zend_compile: Add support for %d to sprintf() optimization (#14561)
* zend_compile: Rename `string_placeholder_count` to `placeholder_count` in `zend_compile_func_sprintf()`

This is intended to make the diff of a follow-up commit smaller.

* zend_compile: Add support for `%d` to `sprintf()` optimization

This extends the existing `sprintf()` optimization by support for the `%d`
placeholder, which effectively equivalent to an `(int)` cast followed by a
`(string)` cast.

For a synthetic test using:

    <?php

    $a = 'foo';
    $b = 42;

    for ($i = 0; $i < 100_000_000; $i++) {
        sprintf("%s-%d", $a, $b);
    }

This optimization yields a 1.3× performance improvement:

    $ hyperfine 'sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php' \
          '/tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php'
    Benchmark 1: sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php
      Time (mean ± σ):      3.296 s ±  0.094 s    [User: 3.287 s, System: 0.005 s]
      Range (min … max):    3.213 s …  3.527 s    10 runs

    Benchmark 2: /tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php
      Time (mean ± σ):      4.300 s ±  0.025 s    [User: 4.290 s, System: 0.007 s]
      Range (min … max):    4.266 s …  4.334 s    10 runs

    Summary
      sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php ran
        1.30 ± 0.04 times faster than /tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php

* Fix sprintf_rope_optimization_003.phpt test expecation for 32-bit integers

* zend_compile: Indent switch-case labels in zend_compile_func_sprintf()

* Add GMP test to sprintf() rope optimization

* Add `%s` test case to sprintf() GMP test
2024-06-17 17:07:50 +02:00
Bob Weinand
6a2c5318f9
Optimize observers (#13649)
Inline the lookup whether a function is observed at all.
This strategy is also used for FRAMELESS calls. If the frameless call is observed, we instead allocate a call frame and push the arguments, to call the the function afterwards.
Doing so is still a performance benefit as opposed to executing individual INIT_FCALL+SEND_VAL ops. Thus, even if the frameless call turns out to be observed, the call overhead is slightly lower than before.
If the internal function is not observed at all, the unavoidable overhead is fetching the FLF zend_function pointer and the run-time cache needs to be inspected.

As part of this work, it turned out to be most viable to put the result operand on the ZEND_OP_DATA instead of ZEND_FRAMELESS_ICALL_3, allowing seamless interoperability with the DO_ICALL opcode.
This is a bit unusual in comparison to all other ZEND_OP_DATA usages, but seems to not pose problems overall.

There is also a small issue resolved: trampolines would always use the ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER function due to zend_observer_fcall_op_array_extension being set to -1 too late.
2024-06-15 14:42:27 +02:00
Tim Düsterhus
1e7aac315e
zend_compile: Optimize sprintf() into a rope (#14546)
* zend_compile: Add `zend_compile_rope_finalize()`

This just extracts the implementation as-is into a dedicated function to make
it reusable in preparation of a future commit.

* zend_compile: Use clearer parameter names for `zend_compile_rope_finalize()`

* zend_compile: Fix `zend_compile_rope_finalize()` for ropes containing a single constant string

Without this Opcache will trigger a use-after-free in
`zend_optimizer_compact_literals()`.

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>

* zend_compile: Optimize `sprintf()` into a rope

This optimization will compile `sprintf()` using only `%s` placeholders into a
rope at compile time, effectively making those calls equivalent to the use of
string interpolation, with the added benefit of supporting arbitrary
expressions instead of just expressions starting with a `$`.

For a synthetic test using:

    <?php

    $a = 'foo';
    $b = 'bar';

    for ($i = 0; $i < 100_000_000; $i++) {
    	sprintf("%s-%s", $a, $b);
    }

This optimization yields a 2.1× performance improvement:

    $ hyperfine 'sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php' \
          '/tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php'
    Benchmark 1: sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php
      Time (mean ± σ):      1.869 s ±  0.033 s    [User: 1.865 s, System: 0.003 s]
      Range (min … max):    1.840 s …  1.945 s    10 runs

    Benchmark 2: /tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php
      Time (mean ± σ):      4.011 s ±  0.034 s    [User: 4.006 s, System: 0.005 s]
      Range (min … max):    3.964 s …  4.079 s    10 runs

    Summary
      sapi/cli/php -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php ran
        2.15 ± 0.04 times faster than /tmp/unoptimized -d zend_extension=php-src/modules/opcache.so -d opcache.enable_cli=1 test.php

This optimization comes with a small and probably insignificant behavioral
change: If one of the values cannot be (cleanly) converted to a string, for
example when attempting to insert an object that is not `Stringable`, the
resulting Exception will naturally not show the `sprintf()` call in the
resulting stack trace, because there is no call to `sprintf()`.

Nevertheless it will correctly point out the line of the `sprintf()` call as
the source of the Exception, pointing the user towards the correct location.

* zend_compile: Eagerly handle empty format strings in `sprintf()` optimization

* zend_compile: Add additional explanatory comments to zend_compile_func_sprintf()

* Add zero-argument test to sprintf_rope_optimization_001.phpt

---------

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
2024-06-13 10:41:45 +02:00
Peter Kokot
5d3fab9334
Sync #if/ifdef/defined (#14520)
These are either undefined or defined (to value 1):
- __DragonFly__
- __FreeBSD__
- HAS_MCAST_EXT
- HAVE_GETCWD
- HAVE_GETWD
- HAVE_GLIBC_ICONV
- HAVE_JIT
- HAVE_LCHOWN
- HAVE_NL_LANGINFO
- HAVE_RL_CALLBACK_READ_CHAR
- HAVE_RL_ON_NEW_LINE
- HAVE_SQL_EXTENDED_FETCH
- HAVE_UTIME

Follow up of GH-5526 (-Wundef)
2024-06-11 22:47:05 +02:00
Ilija Tovilo
2c91b7364b
Also use zval_get_double for op1 in pow comp time check
Mostly for consistency, but this will also allow evaluating more expressions at
compile time.
2024-05-22 16:30:03 +02:00
Jorg Sowa
23afe57f01
Added deprecation Division by zero when using power with zero as base and negative exponent
RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number

Closes GH-13128
2024-05-22 15:05:47 +02:00
Cristian Rodríguez
8e62e2b829
Mark multple functions as static (#13864)
* Mark many functions as static

Multiple functions are missing the static qualifier.

* remove unused struct sigactions

struct sigaction act, old_term, old_quit, old_int;
all unused.

* optimizer: minXOR and maxXOR are unused
2024-05-22 13:11:46 +02:00
divinity76
dabafc7b8e
bool "must" be used instead. (#14287) 2024-05-21 13:10:44 +02:00
Ilija Tovilo
600d591cae
Omit FETCH_THIS in closures
Non-static closures are guaranteed to have $this. The existing comment
highlights this, but fails to handle it correctly.

Closes GH-14181
2024-05-16 12:28:11 +02:00
Ilija Tovilo
1c30c5e707
Print location on class redeclaration
Fixes GH-13950
Closes GH-13999
2024-04-30 14:34:43 +02:00
Ilija Tovilo
7a10b97137
Merge branch 'PHP-8.3'
* PHP-8.3:
  Add missing COMPILE_IGNORE_OTHER_FILES check for static calls
2024-04-17 22:40:24 +02:00
Ilija Tovilo
3d86d9acc1
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Add missing COMPILE_IGNORE_OTHER_FILES check for static calls
2024-04-17 22:39:48 +02:00
Ilija Tovilo
1acd7a0919
Add missing COMPILE_IGNORE_OTHER_FILES check for static calls
Closes GH-13986
2024-04-17 22:39:05 +02:00
Tim Düsterhus
08b2ab22f4
Include the source location in Closure names (#13550)
* Include the source location in Closure names

This change makes stack traces involving Closures, especially multiple
different Closures, much more useful, because it's more easily visible *which*
closure was called for a given stack frame.

The implementation is similar to that of anonymous classes which already
include the file name and line number within their generated classname.

* Update scripts/dev/bless_tests.php for closure naming

* Adjust existing tests for closure naming

* Adjust tests for closure naming that were not caught locally

* Drop the namespace from closure names

This is redundant with the included filename.

* Include filename and line number as separate keys in Closure debug info

* Fix test

* Fix test

* Include the surrounding class and function name in closure names

* Fix test

* Relax test expecations

* Fix tests after merge

* NEWS / UPGRADING
2024-04-12 18:21:13 +02:00
Máté Kocsis
2079da0158
Fix #13865 Improve parameter and return value related deprecation messages (#13913)
I added the function/method name to some compile-time deprecation messages which are related to parameters/return values. Consistently with the other similar error messages, I included the function/method name at the start of the message.
2024-04-08 22:20:32 +02:00
Máté Kocsis
330cc5cdb2
Deprecate implicit nullable parameter types (#12959)
RFC: https://wiki.php.net/rfc/deprecate-implicitly-nullable-types

Co-authored-by: Gina Peter Banyard <girgias@php.net>
2024-03-13 21:40:26 +01:00
Ilija Tovilo
980f7bd2c9
Implement INIT_FCALL offset optimization
Closes GH-13634
2024-03-12 14:13:57 +01:00
Máté Kocsis
f2e199e878
Implement "support doc comments for internal classes and functions" (#13266)
Fixes #13130
2024-02-25 08:41:31 +01:00
Ilija Tovilo
18cdfd3f51
Skip frameless functions with zend_execute_internal
zend_execute_internal is used to intercept function calls. We must use the
DO_FCALL opcode in this instance.
2024-02-07 16:05:15 +01:00
Ilija Tovilo
631bc81607
Implement stackless internal function calls
Co-authored-by: Dmitry Stogov <dmitry@zend.com>

Closes GH-12461
2024-02-06 17:42:28 +01:00
Niels Dossche
fe064d7f12 Fix GH-13142: Undefined variable name is shortened when contains \0
Uses the new %S formatter and introduces the necessary changes and
helpers.
2024-01-20 23:49:13 +01:00
Ilija Tovilo
ffc250d245
Add runtime type inference verification
Co-authored-by: Dmitry Stogov <dmitry@zend.com>

Closes GH-12930
2024-01-19 09:29:14 +01:00
Máté Kocsis
d84ed03a68 Improve error messages related to void/never return types of methods 2024-01-14 16:04:23 +01:00
Máté Kocsis
012ec21def
Remove unused parameter from zend_compile_typename()
The force_allow_null parameter is always false, therefore it is not needed. This simplification paves the road for deprecating implicitly nullable parameter types.
2023-12-24 14:14:35 +01:00
Arnaud Le Blanc
6aa70b577d WS 2023-12-10 13:24:49 +01:00
Arnaud Le Blanc
b1516d95e0 Clarify the stack limit exception message
Make it clearer why the size is not exactly zend.max_allowed_stack_size
2023-12-10 13:20:21 +01:00
Ilija Tovilo
4ba5699903
Fix invalid returned opcode for memoized expressions
Closes GH-12345
2023-10-03 14:01:43 +02:00
Ilija Tovilo
011071a3b3
Improve invalid cpp modifier message
The ZEND_MODIFIER_TARGET_CPP should really have been called _PARAM, but we
shouldn't break API at this point.

Fixes GH-12069
Closes GH-12175
2023-09-11 16:23:43 +02:00
Ilija Tovilo
c2bb9bc0df
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix zend_separate_if_call_and_write for FUNC_ARGs
2023-09-07 14:26:09 +02:00
Ilija Tovilo
fa9cef8b47
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix zend_separate_if_call_and_write for FUNC_ARGs
2023-09-07 14:25:43 +02:00
Ilija Tovilo
748adf18fc
Fix zend_separate_if_call_and_write for FUNC_ARGs
Fixes GH-12102
Closees GH-12140
2023-09-07 14:25:11 +02:00
Cristian Rodríguez
782ffd761b
Use a single version of strnlen (#12015)
* Zend: Make zend_strnlen available for use outside zend_compile

* exif: remove local php_strnlen, use zend_strnlen instead

* main: remove local strnlen, use zend_strnlen instead

* phar: remove local strnlen, use zend_strnlen
2023-08-22 17:40:24 +02:00
ju1ius
7f1c3bf09b
Adds support for DNF types in internal functions and properties (#11969)
Note that this does not add support for items generated by gen_stubs,
only for items registered dynamically via the Zend API.

Closes GH-10120
2023-08-19 00:11:06 +01:00
Ilija Tovilo
1b9ff16f92
Merge branch 'PHP-8.2'
* PHP-8.2:
  Remove redundant condition
2023-08-17 18:55:51 +02:00
Ilija Tovilo
d016c49cf5
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Remove redundant condition
2023-08-17 18:55:45 +02:00
Ilija Tovilo
dd01c74a6f
Remove redundant condition
Never refactor code just before pushing
2023-08-17 18:54:30 +02:00
Ilija Tovilo
48ede64506
Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix segfault in format_default_value due to unexpected enum/object
2023-08-17 18:44:37 +02:00
Ilija Tovilo
9437aa9a8e
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix segfault in format_default_value due to unexpected enum/object
2023-08-17 18:43:49 +02:00
Ilija Tovilo
f78d1d0d10
Fix segfault in format_default_value due to unexpected enum/object
Evaluating constants at comptime can result in arrays that contain objects. This
is problematic for printing the default value of constant ASTs containing
objects, because we don't actually know what the constructor arguments were.
Avoid this by not propagating array constants.

Fixes GH-11937
Closes GH-11947
2023-08-17 18:43:11 +02:00
Ilija Tovilo
db4dba6702
Move opnum_start for goto for clarification (#11911)
opnum_start denotes the start of the ZEND_FREE block of skipped consuming
opcodes. Storing the number before zend_compile_expr(..., label_ast) makes it
seem like it denotes the start of the label block. However, label_ast must only
be a zval string AST, and as such never results in an actual opcode.
2023-08-09 11:38:54 +02:00