The following code poses a problem in the JIT:
```php
class A {
public $prop = 1;
}
class B extends A {
public $prop = 1 {
get => parent::$prop::get() * 2;
}
}
function test(A $a) {
var_dump($a->prop);
}
test(new B);
```
The JIT would assume A::$prop in test() could be accessed directly
through OBJ_PROP_NUM(). However, since child classes can add new hooks
to existing properties, this assumption no longer holds.
To avoid introducing more JIT checks, a hooked property that overrides a
unhooked property now results in a separate zval slot that is used
instead of the parent slot. This causes the JIT to pick the slow path
due to an IS_UNDEF value in the parent slot.
zend_class_entry.properties_info_table poses a problem in that
zend_get_property_info_for_slot() and friends will be called using the
child slot, which does not store its property info, since the parent
slot already does. In this case, zend_get_property_info_for_slot() now
provides a fallback that will iterate all property infos to find the
correct one.
This also uncovered a bug (see Zend/tests/property_hooks/dump.phpt)
where the default value of a parent property would accidentally be
inherited by the child property.
Fixes GH-17376
Closes GH-17870
Fiber switching was disabled during destructor execution due to conflicts
with the garbage collector. This unfortunately introduces a function color
problem: destructors can not call functions that may switch Fibers.
In this change we update the GC so that Fiber switching during GC is safe. In
turn we allow Fiber switching during destrutor execution.
The GC executes destructors in a dedicated Fiber. If a destructor suspends, the
Fiber is owned by userland and a new dedicated Fiber is created to execute the
remaining destructors. Destructor suspension results in a resurection of the
object, which is handled as usual: The object is not considered garbage anymore,
but may be collected in a later run.
When the GC is executed in the main context (not in a Fiber), then destructors
are executed in the main context as well because there is no risk of conflicting
with GC in this case (main context can not suspend).
Fixes GH-11389
Closes GH-13460
Now that constants can contain objects (currently only enums),
we should destroy them before we free the object store, otherwise
there will be false positive leak reports.
This doesn't affect the fast_shutdown sequence.
We're starting to see a mix between uses of zend_bool and bool.
Replace all usages with the standard bool type everywhere.
Of course, zend_bool is retained as an alias.
We only need to do this once we're running destructors. The current
approach interferes with some event loop code that runs everything
inside a shutdown function.
This might happen if OBJ_RELEASE is used on an object that was already
released by GC. Specific cases of this issue were previously fixed in
ffaee27478 and
72104d2b6e, however the issue still
affects 3rd-party extensions using OBJ_RELEASE.
The whole GC type NULL + OBJ_IS_VALID + IS_FREE_CALLED system seems
overly complicated and can probably be simplified in 7.4.
This patch removes the so called local variables defined per
file basis for certain editors to properly show tab width, and
similar settings. These are mainly used by Vim and Emacs editors
yet with recent changes the once working definitions don't work
anymore in Vim without custom plugins or additional configuration.
Neither are these settings synced across the PHP code base.
A simpler and better approach is EditorConfig and fixing code
using some code style fixing tools in the future instead.
This patch also removes the so called modelines for Vim. Modelines
allow Vim editor specifically to set some editor configuration such as
syntax highlighting, indentation style and tab width to be set in the
first line or the last 5 lines per file basis. Since the php test
files have syntax highlighting already set in most editors properly and
EditorConfig takes care of the indentation settings, this patch removes
these as well for the Vim 6.0 and newer versions.
With the removal of local variables for certain editors such as
Emacs and Vim, the footer is also probably not needed anymore when
creating extensions using ext_skel.php script.
Additionally, Vim modelines for setting php syntax and some editor
settings has been removed from some *.phpt files. All these are
mostly not relevant for phpt files neither work properly in the
middle of the file.
The $Id$ keywords were used in Subversion where they can be substituted
with filename, last revision number change, last changed date, and last
user who changed it.
In Git this functionality is different and can be done with Git attribute
ident. These need to be defined manually for each file in the
.gitattributes file and are afterwards replaced with 40-character
hexadecimal blob object name which is based only on the particular file
contents.
This patch simplifies handling of $Id$ keywords by removing them since
they are not used anymore.
Prohibit direct update of GC_REFCOUNT(), GC_SET_REFCOUNT(), GC_ADDREF() and GC_DELREF() shoukf be instead.
Added mactros to validate reference-counting (disabled for now).
These macros are going to be used to eliminate race-condintions during reference-counting on data shared between threads.
Without these zend_trys we may
a) leak the object (fine)
b) don't add it to the free list (also fine, we just lose an
object store bucket)
c) don't remove it from the GC root buffer (also fine, because GC
explicitly checks for both FREE_CALLED and invalid buckets)
Corrupted class entries on shutdown when a destructor spawns another object
(C) 2017 CommerceByte Consulting
When zend_objects_store_call_destructors() is called from the shutdown sequence -
it's calling the dtor's for remaining objects one by one in sequence of object handles.
If the dtor spawns one or more objects, and the new objects happen to reuse the old handles -
their dtor's are not called in this cycle.
The dtor's are called later on, when zend_deactivete() kicks in, and the static property lists in the class entries are freed.
This causes "Undefined static property" errors, and/or SIGSEGV.
Solution:
zend_object_store.no_reuse field is added
Set to 0 on initialization, set to 1 on the shutdown sequence.
zend_objects_store_put(zend_object *) checks the no_reuse flag, and never reuses the old handle slots if set.
This way, the dtor's for newly spawned objects are guaranteed to be called in the zend_objects_store_call_destructors() loop.