Skip to content

Commit 80640ca

Browse files
committed
Zend: factor out guarded lazy-proxy forwarding in object handlers
1 parent dfba0e8 commit 80640ca

1 file changed

Lines changed: 39 additions & 39 deletions

File tree

Zend/zend_object_handlers.c

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,23 @@ ZEND_API uint32_t *zend_get_recursion_guard(zend_object *zobj)
669669
return &Z_GUARD_P(zv);
670670
}
671671

672+
static zend_always_inline zend_object *zend_lazy_proxy_get_guarded_instance(
673+
zend_object *zobj, zend_string *name, uint32_t guard_type)
674+
{
675+
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
676+
&& zend_lazy_object_initialized(zobj))) {
677+
zend_object *instance = zend_lazy_object_get_instance(zobj);
678+
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
679+
uint32_t *instance_guard = zend_get_property_guard(instance, name);
680+
if ((*instance_guard) & guard_type) {
681+
return instance;
682+
}
683+
}
684+
}
685+
686+
return NULL;
687+
}
688+
672689
ZEND_COLD static void zend_typed_property_uninitialized_access(const zend_property_info *prop_info, zend_string *name)
673690
{
674691
zend_throw_error(NULL, "Typed property %s::$%s must not be accessed before initialization",
@@ -896,21 +913,16 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
896913
* guard is already set for this property, we are inside a recursive
897914
* call from the real instance's __get/__isset. Forward directly to
898915
* the real instance to avoid double invocation. (GH-21478) */
899-
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
900-
&& zend_lazy_object_initialized(zobj))) {
901-
zend_object *instance = zend_lazy_object_get_instance(zobj);
902-
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
903-
uint32_t *instance_guard = zend_get_property_guard(instance, name);
904-
uint32_t guard_type = ((type == BP_VAR_IS) && zobj->ce->__isset)
905-
? IN_ISSET : IN_GET;
906-
if ((*instance_guard) & guard_type) {
907-
retval = zend_std_read_property(instance, name, type, cache_slot, rv);
908-
if (retval == &EG(uninitialized_zval)) {
909-
ZVAL_NULL(rv);
910-
retval = rv;
911-
}
912-
return retval;
916+
{
917+
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name,
918+
((type == BP_VAR_IS) && zobj->ce->__isset) ? IN_ISSET : IN_GET);
919+
if (instance) {
920+
retval = zend_std_read_property(instance, name, type, cache_slot, rv);
921+
if (retval == &EG(uninitialized_zval)) {
922+
ZVAL_NULL(rv);
923+
retval = rv;
913924
}
925+
return retval;
914926
}
915927
}
916928

@@ -1262,14 +1274,10 @@ found:;
12621274
/* For initialized lazy proxies: if the real instance's __set guard
12631275
* is already set, we are inside a recursive call from the real
12641276
* instance's __set. Forward directly to avoid double invocation. */
1265-
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
1266-
&& zend_lazy_object_initialized(zobj))) {
1267-
zend_object *instance = zend_lazy_object_get_instance(zobj);
1268-
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
1269-
uint32_t *instance_guard = zend_get_property_guard(instance, name);
1270-
if ((*instance_guard) & IN_SET) {
1271-
return zend_std_write_property(instance, name, value, cache_slot);
1272-
}
1277+
{
1278+
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name, IN_SET);
1279+
if (instance) {
1280+
return zend_std_write_property(instance, name, value, cache_slot);
12731281
}
12741282
}
12751283

@@ -1670,15 +1678,11 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
16701678
/* For initialized lazy proxies: if the real instance's __unset guard
16711679
* is already set, we are inside a recursive call from the real
16721680
* instance's __unset. Forward directly to avoid double invocation. */
1673-
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
1674-
&& zend_lazy_object_initialized(zobj))) {
1675-
zend_object *instance = zend_lazy_object_get_instance(zobj);
1676-
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
1677-
uint32_t *instance_guard = zend_get_property_guard(instance, name);
1678-
if ((*instance_guard) & IN_UNSET) {
1679-
zend_std_unset_property(instance, name, cache_slot);
1680-
return;
1681-
}
1681+
{
1682+
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name, IN_UNSET);
1683+
if (instance) {
1684+
zend_std_unset_property(instance, name, cache_slot);
1685+
return;
16821686
}
16831687
}
16841688

@@ -2498,14 +2502,10 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
24982502
/* For initialized lazy proxies: if the real instance's __isset guard
24992503
* is already set, we are inside a recursive call from the real
25002504
* instance's __isset. Forward directly to avoid double invocation. */
2501-
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
2502-
&& zend_lazy_object_initialized(zobj))) {
2503-
zend_object *instance = zend_lazy_object_get_instance(zobj);
2504-
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
2505-
uint32_t *instance_guard = zend_get_property_guard(instance, name);
2506-
if ((*instance_guard) & IN_ISSET) {
2507-
return zend_std_has_property(instance, name, has_set_exists, cache_slot);
2508-
}
2505+
{
2506+
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name, IN_ISSET);
2507+
if (instance) {
2508+
return zend_std_has_property(instance, name, has_set_exists, cache_slot);
25092509
}
25102510
}
25112511

0 commit comments

Comments
 (0)