[php-src] Issue #11002: [Zend] Why is GC_FLAGS_SHIFT defined as 0 and twice?
| From: | stkeke | Date: | Mon, 03 Apr 2023 14:10:16 +0000 |
| Subject: | [php-src] Issue #11002: [Zend] Why is GC_FLAGS_SHIFT defined as 0 and twice? | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-244089@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/11002
Author: stkeke
### Description
_(look like an issue in source code, but not sure. put it here as it is easier to refer to source
code and commits in github)_
I am looking at
zend_refcounted.h file and found a group of macro definitions, one of
which I hardly make sense -
1) why GC_FLAGS_SHIFT is defined as 0 rather than 4 for
access FLAGS bits?
2) macros below are defined twice - one time in zend_types.h and another time in
zend_refcounted.h without comments for reason although they have same value?
From commit https://github.com/php/php-src/commit/eb34c28fed24d0e4711dd4a04c19d0f95dabc5e9#diff-dca4782c62f10b418ea7193e4641e688ffd7a9c97869f2b1a3a96e28da5653aa,
looks like it is trying to split zend_types.h.
I tried to comment out macro definitions from zend_types.h and still can make a successful build.
https://github.com/php/php-src/blob/master/Zend/zend_types.h#L571
https://github.com/php/php-src/blob/master/Zend/zend_refcounted.h#L26
```c
#define GC_TYPE_MASK 0x0000000f
#define GC_FLAGS_MASK 0x000003f0
#define GC_INFO_MASK 0xfffffc00
#define GC_FLAGS_SHIFT 0
#define GC_INFO_SHIFT 10
```
I know zend_refcount_h has a member type_info, which looks like it has the
format of
| INFO | FLAGS | TYPE |
|-|-|-|
|22bits|6bits|4bits|
|-|-|-|
In function zval_gc_flags, if we only right shift 0 bits, why we need to define this
macro?
```c
// This function looks weird with GC_FLAGS_SHIFT=0
static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) {
return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT);
}
// I can understand this function
static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) {
return (gc_type_info & GC_TYPE_MASK);
}
// I can understand this function
static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
return (gc_type_info >> GC_INFO_SHIFT);
}
```
```c
typedef struct _zend_refcounted_h {
uint32_t refcount; /* reference counter 32-bit */
union {
uint32_t type_info;
} u;
} zend_refcounted_h;
`
### PHP Version
PHP 8.3.0-dev
### Operating System
All OS