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

360 Commits

Author SHA1 Message Date
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
Arnaud Le Blanc
6e6a850cb9 Followup GH-19022
* Fix zend_call_trampoline_arginfo arg name

Name is "arguments" in documentation:
https://www.php.net/__call#language.oop5.overloading.methods

* Use zend_call_trampoline_arginfo in zend_get_call_trampoline_func()

* Copy the original arg_info in zend_closure_from_frame

None of these changes are observable, but this is cleaner, and this becomes observable in GH-20848.

Closes GH-20951
2026-01-16 13:40:31 +01:00
Arnaud Le Blanc
626f3c3c7c Unify arg info representation for internal and user functions
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
2025-12-15 16:50:49 +01:00
Gina Peter Banyard
7815ab9b22 Zend: add const qualifiers when possible for _zend_execute_data.func related uses (#20263)
The initial motivation was to see if it is possible to make the `func` field of `_zend_execute_data` constant.

For various reasons, this is not possible, but the added `const` qualifiers during this exploration remain useful.
2025-10-29 13:22:56 +00:00
Gina Peter Banyard
275ec6f335 Zend: make zend_copy_parameters_array() private (#20265)
And slightly refactor implementation.
2025-10-25 22:36:09 +01:00
Tim Düsterhus
ef1b5ae61b Zend: Use return true / return false for functions returning bool
Changes done with Coccinelle:

    @r1@
    identifier fn;
    typedef bool;
    symbol false;
    symbol true;
    @@

    bool fn ( ... )
    {
    <...
    return
    (
    - 0
    + false
    |
    - 1
    + true
    )
    ;
    ...>
    }

Coccinelle patch sourced from
torvalds/linux@46b5c9b856.
2025-09-24 18:51:40 +02:00
Ilija Tovilo
6e1b1900f0 Mark enums and static fake closures as not collectable
Closes GH-19866
2025-09-22 23:27:33 +02:00
Alexandre Daubois
273d9e2901 [RFC] Deprecate closure binding issues (#19510)
https://wiki.php.net/rfc/deprecations_php_8_5
2025-08-24 00:10:18 -07:00
Ilija Tovilo
eb65ec41b7 Implement Closure::getCurrent() to retrieve current closure
Fixes GH-18163
Closes GH-18167
2025-07-21 16:07:49 +02:00
Tim Düsterhus
45d1acf916 Zend: Fix reference counting for Closures in const-expr (#17853)
* Clean up closure static variable handling

* Zend: Fix reference counting for Closures in const-expr

Fixes php/php-src#17851

---------

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
2025-03-27 10:11:44 +01:00
Tim Düsterhus
da1e254652 Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix `ReflectionFunction::isDeprecated()` for materialized `__call()` (#17914)
2025-02-27 14:48:24 +01:00
Tim Düsterhus
2e999bad34 Fix ReflectionFunction::isDeprecated() for materialized __call() (#17914)
* Fix `ReflectionFunction::isDeprecated()` for materialized `__call()`

Fixes php/php-src#17913

* NEWS
2025-02-27 14:48:08 +01:00
Niels Dossche
a9eddae103 Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix GH-17866: zend_mm_heap corrupted error after upgrading from 8.4.3 to 8.4.4
2025-02-24 21:42:21 +01:00
Niels Dossche
2542357b6d Fix GH-17866: zend_mm_heap corrupted error after upgrading from 8.4.3 to 8.4.4
This regressed in GH-17592.
The function is with its attributes HashTable* is copied in
zend_get_closure_invoke_method() but its refcount is not increased.
This caused a crash in the Symfony demo page.

Closes GH-17880.
2025-02-24 21:39:55 +01:00
Gina Peter Banyard
e40543a401 zend_closures.c: In Closure::__invoke() call the closure directly (#17372)
This prevents a bunch of indirection which ultimately calls `zend_closure_get_closure()` anyway via the `get_closure` object handler.
2025-01-07 09:20:36 +00:00
Ilija Tovilo
9a093e753a Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix propagation of ZEND_ACC_RETURN_REFERENCE for call trampoline
2024-10-22 14:49:27 +02:00
Ilija Tovilo
5eddcb313e Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix propagation of ZEND_ACC_RETURN_REFERENCE for call trampoline
2024-10-22 14:48:58 +02:00
Ilija Tovilo
8720063c4e Fix propagation of ZEND_ACC_RETURN_REFERENCE for call trampoline
Fixes GH-16515
Closes GH-16529
2024-10-22 14:47:01 +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
Niels Dossche
700fbca58d Change getThis() into ZEND_THIS where possible (#13641) 2024-03-08 22:19:06 +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
Levi Morrison
8fb51d4fe4 Set func pointer to null in Closure __invoke (#12275) 2023-09-25 08:27:23 -06:00
Ilija Tovilo
baf74ed1a4 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix freeing of incompletely initialized closures
2023-09-04 15:39:39 +02:00
Ilija Tovilo
6850a040f3 Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix freeing of incompletely initialized closures
2023-09-04 15:39:20 +02:00
Ilija Tovilo
af2110e664 Fix freeing of incompletely initialized closures
Addref to relevant fields before allocating any memory. Also only set/remove the
ZEND_ACC_HEAP_RT_CACHE flag after allocating memory.

Fixes GH-12073
Closes GH-12074
2023-09-04 15:35:39 +02:00
Niels Dossche
5c789806ef Fix GH-11406: segfault with unpacking and magic method closure
The magic method trampoline closure may be variadic. However, the
arg_info for the variadic argument was not set, resulting in a crash
both in reflection and in the VM.

Fix it by creating an arg_info containing a single element in case of
the variadic case. The variadic argument is the last one (and in this
case only one) in the arg_info array.

We make sure the argument info is equivalent to the argument info of
`$closure` of the following code snippet:
```
function foo(...$arguments) {}
$closure = foo(...);
```

Closes GH-11417.
2023-06-13 17:39:47 +02:00
Niels Dossche
61e1f8aaeb Let closure created from magic method accept named parameters
Implements GH-11348.

Closes GH-11364.
2023-06-05 20:03:09 +02:00
George Peter Banyard
9ce6980b4d Use known zend_string pointer to check for equality instead of C strings (#11370)
* Compare __invoke magic method name with known zend_string pointer

* Compare __sleep/__wakeup magic method name with known zend_string pointer
2023-06-05 13:59:04 +01:00
Ilija Tovilo
0b1d750d91 Allow arbitrary expressions in static variable initializer
Closes GH-9301
2023-05-24 20:17:31 +02:00
Christoph M. Becker
bf1cfc0753 Revert GH-10300
Cf. <https://github.com/php/php-src/pull/10220#issuecomment-1383739816>.

This reverts commit 68ada76f9a.
his reverts commit 45384c6e20.
This reverts commit ef7fbfd710.
This reverts commit 9b9ea0d7c6.
This reverts commit f15747c26b.
This reverts commit e883ba93c4.
This reverts commit 7e87551c37.
This reverts commit 921274d2b8.
This reverts commit fc1f528e5e.
This reverts commit 0961715cda.
This reverts commit a93f264526.
This reverts commit 72dd94e1c6.
This reverts commit 29b2dc8964.
This reverts commit 05c7653bba.
This reverts commit 5190e5c260.
This reverts commit 6b55bf228c.
This reverts commit 184b4a12d3.
This reverts commit 4c31b7888a.
This reverts commit d44e9680f0.
This reverts commit 4069a5c43f.
2023-01-16 12:22:54 +01:00
Max Kellermann
68ada76f9a Zend/zend_closures: include cleanup 2023-01-15 15:07:58 +00:00
Dmitry Stogov
ff85649431 Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix a memory leak in tracig JIT when the same closure is called through Closure::call() and natively.
2022-11-22 12:29:36 +03:00
Dmitry Stogov
45cb3f917a Fix a memory leak in tracig JIT when the same closure is called through Closure::call() and natively.
Closure::call() makes a temporary copy of original closure function, modifies its
scope, resets ZEND_ACC_CLOSURE flag and call it through zend_call_function().
As result the same function may be called with and without
ZEND_ACC_CLOSURE flag, that confuses JIT and may lead to memory leak or
even worse memory errors.

The patch allocates "fake" closure object and keep ZEND_ACC_CLOSURE flag
to always behave in the same way.
2022-11-21 17:41:16 +03:00
Bob Weinand
ef5ed06d3c Merge branch 'PHP-8.2' 2022-11-02 16:55:42 +01:00
Bob Weinand
8e49d7f32f Delay releasing closures until after observer end 2022-11-02 16:55:13 +01:00
Christoph M. Becker
b2199f9559 Merge branch 'PHP-8.2'
* PHP-8.2:
  Don’t reset func in zend_closure_internal_handler
2022-11-02 14:02:34 +01:00
Florian Sowade
8dabbda8bc Don’t reset func in zend_closure_internal_handler
The pointer is used in _zend_observe_fcall_begin().
2022-11-02 11:46:43 +01:00
Bob Weinand
5a0b68bed7 Revert "Store default object handlers alongside the class entry"
This reverts commit 9e6eab3c13.

Reverted along a01dd9feda.
2022-09-14 11:18:14 +02:00
Bob Weinand
9e6eab3c13 Store default object handlers alongside the class entry
Object handlers being separate from class entries is a legacy inherited from PHP 5. Today it has little benefit to keep them separate: in fact, accessing object handlers usually requires not-so-safe hacks.
While it is possible to swap handlers in a custom installed create_object handler, this mostly is tedious, as well as it requires allocating the object handlers struct at runtime, possibly caching it etc..

This allows extensions, which intend to observe other classes to install their own class handlers.
The life cycle of internal classes may now be simply observed by swapping the class handlers in post_startup stage.
The life cycle of userland classes may be observed by iterating over the new classes in zend_compile_file and zend_compile_string and then swapping their handlers.

In general, this would also be a first step in directly tying the object handlers to classes. Especially given that I am not aware of any case where the object handlers would be different between various instances of a given class.

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
2022-08-31 16:45:27 +02:00
Ilija Tovilo
1f6baa776b Show function name when dumping fake closure (#9306)
Fixes GH-8962
2022-08-12 12:22:55 +02:00
Bob Weinand
b576bb901e Avoid using a stack allocated zend_function in Closure::call, to avoid prevent crashes on bailout
Having a stack allocated zend_function may cause crashes if the stack is polluted between bailout and the actual unwinding in zend_observer_fcall_end_all.

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
2022-07-28 13:04:11 +02:00
Ilija Tovilo
3b92a96610 Convert return type of various object handlers from int to zend_result (#8755) 2022-06-26 01:00:19 +02:00
Ilija Tovilo
19063a84f0 Fix null static_variable_ptr for uncalled fake closures
Closes GH-8083
Closes GH-8109
2022-02-19 11:37:52 +01:00
Dmitry Stogov
a1e0936539 Merge branch 'PHP-8.1'
* PHP-8.1:
  Fix emory leak
2022-02-11 15:16:43 +03:00
Dmitry Stogov
73fed0f028 Fix emory leak
Fixes oss-fuzz #44408
2022-02-11 15:16:08 +03:00
Dmitry Stogov
90b7bde615 Use more compact representation for packed arrays.
- for packed arrays we store just an array of zvals without keys.
- the elements of packed array are accessible throuf as ht->arPacked[i]
  instead of ht->arData[i]
- in addition to general ZEND_HASH_FOREACH_* macros, we introduced similar
  familied for packed (ZEND_HASH_PACKED_FORECH_*) and real hashes
  (ZEND_HASH_MAP_FOREACH_*)
- introduced an additional family of macros to access elements of array
  (packed or real hashes) ZEND_ARRAY_ELEMET_SIZE, ZEND_ARRAY_ELEMET_EX,
  ZEND_ARRAY_ELEMET, ZEND_ARRAY_NEXT_ELEMENT, ZEND_ARRAY_PREV_ELEMENT
- zend_hash_minmax() prototype was changed to compare only values

Because of smaller data set, this patch may show performance improvement
on some apps and benchmarks that use packed arrays. (~1% on PHP-Parser)

TODO:
    - sapi/phpdbg needs special support for packed arrays (WATCH_ON_BUCKET).
    - zend_hash_sort_ex() may require converting packed arrays to hash.
2021-11-03 15:18:26 +03:00
Dmitry Stogov
04cbd84192 Always use direct pointer (not map_ptr slot) to access run_time_cache of a closure instance 2021-10-14 17:21:37 +03:00
Dmitry Stogov
ddaf64b56c Avoid non-immutable map_ptr indirection 2021-10-14 12:16:18 +03:00
Nikita Popov
2cc47a04df Merge branch 'PHP-8.0'
* PHP-8.0:
  Fix Closure::call() on internal method closure
2021-08-27 12:00:07 +02:00
Nikita Popov
2467f759f5 Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4:
  Fix Closure::call() on internal method closure
2021-08-27 11:59:38 +02:00