@@ -345,7 +345,7 @@ struct _zval_struct {
345345 uint32_t num_args ; /* arguments number for EX(This) */
346346 uint32_t fe_pos ; /* foreach position */
347347 uint32_t fe_iter_idx ; /* foreach iterator index */
348- uint32_t property_guard ; /* single property guard */
348+ uint32_t guard ; /* recursion and single property guard */
349349 uint32_t constant_flags ; /* constant flags */
350350 uint32_t extra ; /* not further specified */
351351 } u2 ;
@@ -619,6 +619,22 @@ struct _zend_ast_ref {
619619#define _IS_BOOL 18
620620#define _IS_NUMBER 19
621621
622+ /* guard flags */
623+ #define ZEND_GUARD_PROPERTY_GET (1<<0)
624+ #define ZEND_GUARD_PROPERTY_SET (1<<1)
625+ #define ZEND_GUARD_PROPERTY_UNSET (1<<2)
626+ #define ZEND_GUARD_PROPERTY_ISSET (1<<3)
627+ #define ZEND_GUARD_PROPERTY_MASK 15
628+ #define ZEND_GUARD_RECURSION_DEBUG (1<<4)
629+ #define ZEND_GUARD_RECURSION_EXPORT (1<<5)
630+ #define ZEND_GUARD_RECURSION_JSON (1<<6)
631+
632+ #define ZEND_GUARD_RECURSION_TYPE (t ) ZEND_GUARD_RECURSION_ ## t
633+
634+ #define ZEND_GUARD_IS_RECURSIVE (pg , t ) ((*pg & ZEND_GUARD_RECURSION_TYPE(t)) != 0)
635+ #define ZEND_GUARD_PROTECT_RECURSION (pg , t ) *pg |= ZEND_GUARD_RECURSION_TYPE(t)
636+ #define ZEND_GUARD_UNPROTECT_RECURSION (pg , t ) *pg &= ~ZEND_GUARD_RECURSION_TYPE(t)
637+
622638static zend_always_inline uint8_t zval_get_type (const zval * pz ) {
623639 return pz -> u1 .v .type ;
624640}
@@ -659,8 +675,8 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
659675#define Z_FE_ITER (zval ) (zval).u2.fe_iter_idx
660676#define Z_FE_ITER_P (zval_p ) Z_FE_ITER(*(zval_p))
661677
662- #define Z_PROPERTY_GUARD (zval ) (zval).u2.property_guard
663- #define Z_PROPERTY_GUARD_P (zval_p ) Z_PROPERTY_GUARD (*(zval_p))
678+ #define Z_GUARD (zval ) (zval).u2.guard
679+ #define Z_GUARD_P (zval_p ) Z_GUARD (*(zval_p))
664680
665681#define Z_CONSTANT_FLAGS (zval ) (zval).u2.constant_flags
666682#define Z_CONSTANT_FLAGS_P (zval_p ) Z_CONSTANT_FLAGS(*(zval_p))
@@ -859,6 +875,25 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
859875#define Z_PROTECT_RECURSION_P (zv ) Z_PROTECT_RECURSION(*(zv))
860876#define Z_UNPROTECT_RECURSION_P (zv ) Z_UNPROTECT_RECURSION(*(zv))
861877
878+ #define ZEND_GUARD_OR_GC_IS_RECURSIVE (pg , t , zobj ) \
879+ (pg ? ZEND_GUARD_IS_RECURSIVE(pg, t) : GC_IS_RECURSIVE(zobj))
880+
881+ #define ZEND_GUARD_OR_GC_PROTECT_RECURSION (pg , t , zobj ) do { \
882+ if (pg) { \
883+ ZEND_GUARD_PROTECT_RECURSION(pg, t); \
884+ } else { \
885+ GC_PROTECT_RECURSION(zobj); \
886+ } \
887+ } while(0)
888+
889+ #define ZEND_GUARD_OR_GC_UNPROTECT_RECURSION (pg , t , zobj ) do { \
890+ if (pg) { \
891+ ZEND_GUARD_UNPROTECT_RECURSION(pg, t); \
892+ } else { \
893+ GC_UNPROTECT_RECURSION(zobj); \
894+ } \
895+ } while(0)
896+
862897/* All data types < IS_STRING have their constructor/destructors skipped */
863898#define Z_CONSTANT (zval ) (Z_TYPE(zval) == IS_CONSTANT_AST)
864899#define Z_CONSTANT_P (zval_p ) Z_CONSTANT(*(zval_p))
0 commit comments