1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 16:22:37 +01:00

1993 Commits

Author SHA1 Message Date
Dmitry Stogov
0bd3a6b7f2 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix support for TAILCALL VM
  Fix GH-21267: JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property (#21368)
2026-03-16 21:58:32 +03:00
Dmitry Stogov
81504d3db7 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-21267: JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property (#21368)
2026-03-16 21:32:27 +03:00
Ilia Alshanetsky
e1a3a4c9a4 Fix GH-21267: JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property (#21368)
When the JIT defers the IS_UNDEF check for FETCH_OBJ_R to the result
type guard, the deoptimization escape path dispatches to opline->handler
via the trace_escape stub. If opline->handler has been overwritten with
JIT code (e.g. a function entry trace), this creates an infinite loop.

Fix by dispatching to the original VM handler (orig_handler from the
trace extension) instead of going through the trace_escape stub. This
avoids the extra IS_UNDEF guard on every property read while correctly
handling the rare IS_UNDEF case during deoptimization.

Also set current_op_array in zend_jit_trace_exit_to_vm so that the
blacklisted exit deoptimizer can resolve orig_handler, covering the
case where side trace compilation is exhausted.

Closes GH-21368.
2026-03-16 21:31:49 +03:00
Dmitry Stogov
79556df7ee Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-20838: JIT compiler produces wrong arithmetic results (#21383)
2026-03-11 15:23:22 +03:00
Dmitry Stogov
35ee95a827 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-20838: JIT compiler produces wrong arithmetic results (#21383)
2026-03-11 15:23:12 +03:00
Ilia Alshanetsky
80dc4c19d6 Fix GH-20838: JIT compiler produces wrong arithmetic results (#21383)
Insert type guards (CHECK_OP1_TRACE_TYPE / CHECK_OP2_TRACE_TYPE) on the
sensitive bailout paths in ADD/SUB/MUL JIT compilation: the MAY_BE_UNDEF
and non-numeric operand breaks. Guards are only emitted when the traced
operand type is IS_LONG or IS_DOUBLE, ensuring TSSA result type
predictions stay valid for side traces without affecting the normal
numeric fast path.


Fixes GH-20838

Co-authored-by: Dmitry Stogov <dmitrystogov@gmail.com>
2026-03-11 15:22:50 +03:00
Ilija Tovilo
4156b52296 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix preloaded constant erroneously propagated to file-cached script
2026-02-24 17:31:08 +01:00
Ilija Tovilo
8206eb1cb4 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix preloaded constant erroneously propagated to file-cached script
2026-02-24 17:30:14 +01:00
Ilija Tovilo
ec5a1e001d Fix preloaded constant erroneously propagated to file-cached script
Since GH-15021 preloaded constants are propagated to compiled scripts. This is
problematic for file cache, which assumes all referenced zvals are either
persistently allocated or local to the current script. However, preloaded
constants live in shm as immutable, but not persistent.

To solve this, we'd need to duplicate propagated constants in the optimizer when
file cache is used. This is error prone given it needs to happen in many places.
It's debatable whether constant propagation is even correct in this case, as
running the preloaded script on a restart isn't guaranteed to produce the same
result.

Hence, avoid the issue for now by just not relying on preloaded symbols when
file cache is used.

Fixes GH-21052
Closes GH-21281
2026-02-24 17:28:56 +01:00
Ilija Tovilo
db0e365f5a Fix missing reference unwrap for FE_FETCH_R in JIT (GH-21265)
Fixes GH-21264
2026-02-24 02:15:07 +01:00
Ilija Tovilo
94c8e01a06 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix borked SCCP of array containing partial object
2026-02-17 18:12:15 +01:00
Ilija Tovilo
1da4480852 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix borked SCCP of array containing partial object
2026-02-17 18:12:09 +01:00
Ilija Tovilo
1931472f22 Fix borked SCCP of array containing partial object
In SCCP, arrays containing partial objects must be marked as partial so that
their values are not accidentally propagated.

Fixes GH-21227
Closes GH-21232
2026-02-17 18:11:28 +01:00
Ilija Tovilo
fcff846a73 Fix borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization (GH-21121)
Fixes OSS-Fuzz #481014628
Introduced in GH-20628

Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com>
2026-02-09 13:22:35 +01:00
Ilija Tovilo
6173a9a109 VAR|TMP overhaul (GH-20628)
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
2026-01-31 19:44:56 +01:00
Alexandre Daubois
e4935cf601 Merge branch 'PHP-8.5'
* PHP-8.5:
  Core: fix missing deprecation when accessing null array key with JIT (#20883)
2026-01-30 16:19:57 +01:00
Alexandre Daubois
4a6e6077ef Core: fix missing deprecation when accessing null array key with JIT (#20883) 2026-01-30 16:18:33 +01:00
Ilija Tovilo
db24ca5926 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix segfault when preloading constant AST closure
2026-01-29 13:31:38 +01:00
Ilija Tovilo
2f2b421a48 Fix segfault when preloading constant AST closure
Fixes GH-21059
Closes GH-21071
2026-01-29 13:30:41 +01:00
Tim Düsterhus
6a17febe6c zend_compile: Fix array_map() optimization (#21016)
* 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.

Fixes php/php-src#20991.

* zend_compile: Fix array_map() optimization for dynamic function names

Fixes php/php-src#20990.

* zend_compile: Adjust array_map() optimization after review feedback
2026-01-26 08:59:30 +01:00
Ilija Tovilo
95f7e30f4c [skip ci] Fix tmps= count in variation build
Observers add an extra tmp, breaking the expected output.
2026-01-21 16:57:05 +01:00
Ilija Tovilo
f4728ecc57 [skip ci] Move opcache.opt_debug_level tests to ext/opcache
These tests need to live in ext/opcache, or they will break the file cache job.
2026-01-21 16:53:57 +01:00
Ilija Tovilo
aeb8524584 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix segfault in Tracing JIT with object reference (GH-20818)
2026-01-21 00:27:20 +01:00
Ilija Tovilo
2352cc1225 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix segfault in Tracing JIT with object reference (GH-20818)
2026-01-21 00:27:15 +01:00
Chris Hasiński
1db1c7f5c1 Fix segfault in Tracing JIT with object reference (GH-20818)
When FE_RESET_RW executes, it converts the CV to a reference before
checking if the array/object is empty. However, when the JIT creates
exit points for FE_RESET_RW in zend_jit_trace_handler(), it wasn't
updating the stack type for op1 to reflect this change.

This caused side traces compiled from these exit points to have
incorrect type information. The side trace's CV cleanup code would
see IS_OBJECT and generate a direct call to zend_objects_store_del(),
but the actual value was a zend_reference*, causing a segfault.

The fix adds ZEND_FE_RESET_RW to the list of opcodes that temporarily
set their op1 stack type to IS_UNKNOWN before creating exit points.
This follows the same pattern used for ZEND_BIND_INIT_STATIC_OR_JMP.
When IS_UNKNOWN, the JIT falls back to SSA type info which correctly
includes MAY_BE_REF for FE_RESET_RW's op1_def.

Fixes GH-20818
Closes GH-20948
2026-01-21 00:24:14 +01:00
Niels Dossche
9731f11807 Merge branch 'PHP-8.5'
* PHP-8.5:
  Revert "Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT"
2026-01-20 21:05:58 +01:00
Niels Dossche
fd5e45116b Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Revert "Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT"
2026-01-20 21:05:50 +01:00
Niels Dossche
32c0245531 Revert "Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT"
This reverts commit 57c62eb2b3.
2026-01-20 21:05:26 +01:00
Niels Dossche
c8952c7cb7 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT
2026-01-20 18:55:45 +01:00
Niels Dossche
77c9c8c6c0 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT
2026-01-20 18:55:39 +01:00
Niels Dossche
57c62eb2b3 Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT
This is similar to f6c2e40a11 but for minimal JIT + tracing JIT.
Most of the times the tracing JIT shouldn't rely on going to the VM, but
in some cases, like in minimal JIT, it can and then it hits the same
bug.

Closes GH-20897.
2026-01-20 18:55:08 +01:00
Bob Weinand
b95d2ee70a Merge branch 'PHP-8.5'
* PHP-8.5:
  Split the live-ranges of loop variables again (#20865)
2026-01-15 16:17:34 +01:00
Bob Weinand
c878380065 Merge branch 'PHP-8.4' of github.com:php/php-src into PHP-8.5
* 'PHP-8.4' of github.com:php/php-src:
  Split the live-ranges of loop variables again (#20865)
2026-01-15 16:15:29 +01:00
Bob Weinand
27ed48c0be Split the live-ranges of loop variables again (#20865)
* Fix use-after-free in FE_FREE with GC interaction

When FE_FREE with ZEND_FREE_ON_RETURN frees the loop variable during
an early return from a foreach loop, the live range for the loop
variable was incorrectly extending past the FE_FREE to the normal
loop end. This caused GC to access the already-freed loop variable
when it ran after the RETURN opcode, resulting in use-after-free.

Fix by splitting the ZEND_LIVE_LOOP range when an FE_FREE with
ZEND_FREE_ON_RETURN is encountered:
- One range covers the early return path up to the FE_FREE
- A separate range covers the normal loop end FE_FREE
- Multiple early returns create multiple separate ranges

* Split the live-ranges of loop variables again

b0af9ac733 removed the live-range splitting of foreach variables, however it only added handling to ZEND_HANDLE_EXCEPTION.
This was sort-of elegant, until it was realized in 8258b7731b that it would leak the return variable, requiring some more special handling.
At some point we added live tmpvar rooting in 52cf7ab8a2, but this did not take into account already freed loop variables, which also might happen during ZEND_RETURN, which cannot be trivially accounted for, without even more complicated handling in zend_gc_*_tmpvars() functions.

This commit also proposes a simpler way of tracking the loop end in loopvar freeing ops: handle it directly during live range computation rather than during compilation, eliminating the need for opcache to handle it specifically.
Further, opcache was using live_ranges in its basic block computation in the past, which it no longer does. Thus this complication is no longer necessary and this approach should be actually simpler now.

Closes #20766.

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>

---------

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
Co-authored-by: Gustavo Lopes <mail@geleia.net>
2026-01-15 16:13:43 +01:00
Niels Dossche
91f095d2ff Merge branch 'PHP-8.5'
* PHP-8.5:
  Add test for GH-20880 (#20919)
2026-01-12 22:45:50 +01:00
Niels Dossche
c80ac797d4 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Add test for GH-20880 (#20919)
2026-01-12 22:45:43 +01:00
Niels Dossche
1052270001 Add test for GH-20880 (#20919)
Closes GH-20880.
2026-01-12 22:45:24 +01:00
Ilija Tovilo
1ee38a3dcb Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix block_pass JMP[N]Z optimization
2026-01-11 14:56:11 +01:00
Ilija Tovilo
918dc2355e Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix block_pass JMP[N]Z optimization
2026-01-11 14:56:05 +01:00
Ilija Tovilo
f61b1fc036 Fix block_pass JMP[N]Z optimization
In the following optimization:

JMPZ(X,L1) JMP(L2) L1: -> JMPNZ(X,L2) NOP

L1 must not be followed by another block, so that it may safely be followed by
the block containing the JMPNZ. get_next_block() is used to verify L1 is the
direct follower. This function also skips empty blocks, including live, empty
target blocks, which will then implicitly follow the new follow block. This will
result in L1 being followed by two separate blocks, which is not possible.

Resolve this by get_next_block() stopping at target blocks.

Fixes OSS-Fuzz #472563272
Closes GH-20850
2026-01-11 14:55:23 +01:00
Ilija Tovilo
eafbc6b3e6 [skip ci] Fix opcache dump test for VARIATION job 2025-10-24 17:40:18 +02:00
Tim Düsterhus
025e16cb54 zend_compile: Optimize arguments for ZEND_NEW (#20259)
* 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
2025-10-23 09:28:19 +02:00
Ilija Tovilo
5c956f9838 Avoid capturing nested arrow function parameters
Fixes GH-19867
Closes GH-20041
2025-10-03 23:16:21 +02:00
Ilija Tovilo
faa4c7f9e6 Fix flaky gh19984.phpt test
When the parent finishes before the child, we may miss some output from the
child and have the test fail.
2025-10-03 22:25:18 +02:00
Ilija Tovilo
bcd4be7d50 Fix double-free of EG(errors)/persistent_script->warnings on persist of already persisted file
Both processes race to compile warning_replay.inc. Whichever is first will get
to persist the script. The loser will use the script that is already persisted,
and the script that was just compiled is freed.

However, EG(errors) and persistent_script->warnings still refer to the same
allocation, and EG(errors) becomes a dangling pointer. To solve this, we simply
don't free warnings from free_persistent_script() anymore to maintain exclusive
ownership for EG(errors).

Furthermore, we need to adjust a call to zend_emit_recorded_errors() that would
previously use EG(errors), even when persistent_script has been swapped out.

Fixes GH-19984
Closes GH-19995
2025-09-30 22:53:25 +02:00
Gina Peter Banyard
b4b0155f64 opcache: Fix segfault in function JIT due to NAN to bool warning (#19947) 2025-09-24 16:48:02 +01:00
Gina Peter Banyard
320fe2975b core: Warn when coercing NAN to other types
RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types

Closes GH-19573
2025-09-23 11:16:51 +01:00
Gina Peter Banyard
d27e1e1723 core: Add new test for coercions from NAN 2025-09-23 11:14:58 +01:00
Arnaud Le Blanc
f0878c8e30 Merge branch 'PHP-8.4'
* PHP-8.4:
  Handle references after FETCH_OBJ_R with REG destination
2025-09-22 17:57:35 +02:00
Arnaud Le Blanc
32c919b474 Handle references after FETCH_OBJ_R with REG destination
zend_jit_fetch_obj_r_slow_ex() may be used by the function JIT, which doesn't
rely on guards to handle references. Therefore it must deref the property value.

Other variants of zend_jit_fetch_obj_*_slow_ex can not be used used in function
JIT.

Fixes GH-19831
Closes GH-19838
2025-09-22 17:56:57 +02:00