For early observing, there already exists a op_array_ctor hook on zend_extension.
However the goal of the declared_function observer is noting the time when a fully defined function starts existing in the function_tables.
This also prevents the observer being called in case there were compilation errors.
Ultimately, this now gives a consistent behaviour with respect to how it works when opcache is enabled:
- pass_two is done, opcodes and flags are all finalized.
- similarly class_linked notifications also only happen once the class is actually finalized.
- any extension wanting to delay the observer call may add the ZEND_COMPILE_IGNORE_OBSERVER compiler_option, then call it itself.
The intersection type needs to be marked as being allocated on the arena otherwise zend_persist_type() tries to free it and corrupts the Zend MM Heap
Also we only need to allocate the space for a list of size 1 and not the whole length of the intersection type
The issue was that we didn't compute enough cache slots for DNF types.
Nor progressed throught the CE's in the cache slot, meaning we were only checking if the value passed
satisfied the first type of the nested intersection type.
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>
If one tries to use such an alias as a type declaration the following error would be raised:
Fatal error: Cannot use 'int' as class name as it is reserved
The ast node flag constants ZEND_DIM_ALTERNATIVE_SYNTAX and
ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR node have identical values (1<<1),
causing a deprecation notice to be incorrectly emitted before the fatal error
for unsupported syntax.
Fixes GH-9263
Explicitly check for AST_VAR/AST_DIM kind for future compatibility
`AST_PROP`/`AST_METHOD_CALL` and nullsafe variants can also be found in
encapsulated strings - currently they have no flags but they may have flags in
the future. This also clarifies that this deprecation warning can only happen
for AST_VAR/AST_DIM nodes for certain `attr` values.
There are two main motivations to this:
a) The logic for handling internal and userland observation can be unified.
b) Unwinding of observed functions on a bailout does notably not include observers. Even if users of observers were to ensure such handling themselves, it would be impossible to retain the relative ordering - either the user has to unwind all internal observed frames before the automatic unwinding (zend_observer_fcall_end_all) or afterwards, but not properly interleaved.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
RFC: https://wiki.php.net/rfc/dnf_types
This allows to combine union and intersection types together in the following form (A&B)|(X&Y)|T but not of the form (X|A)&(Y|B) or (X|A)&(Y|B)|T.
* Improve union type parsing
Co-authored-by: Sara Golemon <pollita@php.net>