root/Zend/zend_types.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. zval_get_type
  2. zval_refcount_p
  3. zval_set_refcount_p
  4. zval_addref_p
  5. zval_delref_p

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 2.00 of the Zend license,     |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.zend.com/license/2_00.txt.                                |
  11    | If you did not receive a copy of the Zend license and are unable to  |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@zend.com so we can mail you a copy immediately.              |
  14    +----------------------------------------------------------------------+
  15    | Authors: Andi Gutmans <andi@zend.com>                                |
  16    |          Zeev Suraski <zeev@zend.com>                                |
  17    |          Dmitry Stogov <dmitry@zend.com>                             |
  18    |          Xinchen Hui <xinchen.h@zend.com>                            |
  19    +----------------------------------------------------------------------+
  20 */
  21 
  22 /* $Id$ */
  23 
  24 #ifndef ZEND_TYPES_H
  25 #define ZEND_TYPES_H
  26 
  27 #include "zend_portability.h"
  28 #include "zend_long.h"
  29 
  30 #ifdef WORDS_BIGENDIAN
  31 # define ZEND_ENDIAN_LOHI(lo, hi)          hi; lo;
  32 # define ZEND_ENDIAN_LOHI_3(lo, mi, hi)    hi; mi; lo;
  33 # define ZEND_ENDIAN_LOHI_4(a, b, c, d)    d; c; b; a;
  34 # define ZEND_ENDIAN_LOHI_C(lo, hi)        hi, lo
  35 # define ZEND_ENDIAN_LOHI_C_3(lo, mi, hi)  hi, mi, lo,
  36 # define ZEND_ENDIAN_LOHI_C_4(a, b, c, d)  d, c, b, a
  37 #else
  38 # define ZEND_ENDIAN_LOHI(lo, hi)          lo; hi;
  39 # define ZEND_ENDIAN_LOHI_3(lo, mi, hi)    lo; mi; hi;
  40 # define ZEND_ENDIAN_LOHI_4(a, b, c, d)    a; b; c; d;
  41 # define ZEND_ENDIAN_LOHI_C(lo, hi)        lo, hi
  42 # define ZEND_ENDIAN_LOHI_C_3(lo, mi, hi)  lo, mi, hi,
  43 # define ZEND_ENDIAN_LOHI_C_4(a, b, c, d)  a, b, c, d
  44 #endif
  45 
  46 typedef unsigned char zend_bool;
  47 typedef unsigned char zend_uchar;
  48 
  49 typedef enum {
  50   SUCCESS =  0,
  51   FAILURE = -1,         /* this MUST stay a negative number, or it may affect functions! */
  52 } ZEND_RESULT_CODE;
  53 
  54 #ifdef ZEND_ENABLE_ZVAL_LONG64
  55 # ifdef ZEND_WIN32
  56 #  define ZEND_SIZE_MAX  _UI64_MAX
  57 # else
  58 #  define ZEND_SIZE_MAX  SIZE_MAX
  59 # endif
  60 #else
  61 # if defined(ZEND_WIN32)
  62 #  define ZEND_SIZE_MAX  _UI32_MAX
  63 # else
  64 #  define ZEND_SIZE_MAX SIZE_MAX
  65 # endif
  66 #endif
  67 
  68 typedef intptr_t zend_intptr_t;
  69 typedef uintptr_t zend_uintptr_t;
  70 
  71 #ifdef ZTS
  72 #define ZEND_TLS static TSRM_TLS
  73 #define ZEND_EXT_TLS TSRM_TLS
  74 #else
  75 #define ZEND_TLS static
  76 #define ZEND_EXT_TLS
  77 #endif
  78 
  79 typedef struct _zend_object_handlers zend_object_handlers;
  80 typedef struct _zend_class_entry     zend_class_entry;
  81 typedef union  _zend_function        zend_function;
  82 typedef struct _zend_execute_data    zend_execute_data;
  83 
  84 typedef struct _zval_struct     zval;
  85 
  86 typedef struct _zend_refcounted zend_refcounted;
  87 typedef struct _zend_string     zend_string;
  88 typedef struct _zend_array      zend_array;
  89 typedef struct _zend_object     zend_object;
  90 typedef struct _zend_resource   zend_resource;
  91 typedef struct _zend_reference  zend_reference;
  92 typedef struct _zend_ast_ref    zend_ast_ref;
  93 typedef struct _zend_ast        zend_ast;
  94 
  95 typedef int  (*compare_func_t)(const void *, const void *);
  96 typedef void (*swap_func_t)(void *, void *);
  97 typedef void (*sort_func_t)(void *, size_t, size_t, compare_func_t, swap_func_t);
  98 typedef void (*dtor_func_t)(zval *pDest);
  99 typedef void (*copy_ctor_func_t)(zval *pElement);
 100 
 101 typedef union _zend_value {
 102         zend_long         lval;                         /* long value */
 103         double            dval;                         /* double value */
 104         zend_refcounted  *counted;
 105         zend_string      *str;
 106         zend_array       *arr;
 107         zend_object      *obj;
 108         zend_resource    *res;
 109         zend_reference   *ref;
 110         zend_ast_ref     *ast;
 111         zval             *zv;
 112         void             *ptr;
 113         zend_class_entry *ce;
 114         zend_function    *func;
 115         struct {
 116                 uint32_t w1;
 117                 uint32_t w2;
 118         } ww;
 119 } zend_value;
 120 
 121 struct _zval_struct {
 122         zend_value        value;                        /* value */
 123         union {
 124                 struct {
 125                         ZEND_ENDIAN_LOHI_4(
 126                                 zend_uchar    type,                     /* active type */
 127                                 zend_uchar    type_flags,
 128                                 zend_uchar    const_flags,
 129                                 zend_uchar    reserved)     /* call info for EX(This) */
 130                 } v;
 131                 uint32_t type_info;
 132         } u1;
 133         union {
 134                 uint32_t     var_flags;
 135                 uint32_t     next;                 /* hash collision chain */
 136                 uint32_t     cache_slot;           /* literal cache slot */
 137                 uint32_t     lineno;               /* line number (for ast nodes) */
 138                 uint32_t     num_args;             /* arguments number for EX(This) */
 139                 uint32_t     fe_pos;               /* foreach position */
 140                 uint32_t     fe_iter_idx;          /* foreach iterator index */
 141         } u2;
 142 };
 143 
 144 typedef struct _zend_refcounted_h {
 145         uint32_t         refcount;                      /* reference counter 32-bit */
 146         union {
 147                 struct {
 148                         ZEND_ENDIAN_LOHI_3(
 149                                 zend_uchar    type,
 150                                 zend_uchar    flags,    /* used for strings & objects */
 151                                 uint16_t      gc_info)  /* keeps GC root number (or 0) and color */
 152                 } v;
 153                 uint32_t type_info;
 154         } u;
 155 } zend_refcounted_h;
 156 
 157 struct _zend_refcounted {
 158         zend_refcounted_h gc;
 159 };
 160 
 161 struct _zend_string {
 162         zend_refcounted_h gc;
 163         zend_ulong        h;                /* hash value */
 164         size_t            len;
 165         char              val[1];
 166 };
 167 
 168 typedef struct _Bucket {
 169         zval              val;
 170         zend_ulong        h;                /* hash value (or numeric index)   */
 171         zend_string      *key;              /* string key or NULL for numerics */
 172 } Bucket;
 173 
 174 typedef struct _zend_array HashTable;
 175 
 176 struct _zend_array {
 177         zend_refcounted_h gc;
 178         union {
 179                 struct {
 180                         ZEND_ENDIAN_LOHI_4(
 181                                 zend_uchar    flags,
 182                                 zend_uchar    nApplyCount,
 183                                 zend_uchar    nIteratorsCount,
 184                                 zend_uchar    reserve)
 185                 } v;
 186                 uint32_t flags;
 187         } u;
 188         uint32_t          nTableMask;
 189         Bucket           *arData;
 190         uint32_t          nNumUsed;
 191         uint32_t          nNumOfElements;
 192         uint32_t          nTableSize;
 193         uint32_t          nInternalPointer;
 194         zend_long         nNextFreeElement;
 195         dtor_func_t       pDestructor;
 196 };
 197 
 198 /*
 199  * HashTable Data Layout
 200  * =====================
 201  *
 202  *                 +=============================+
 203  *                 | HT_HASH(ht, ht->nTableMask) |
 204  *                 | ...                         |
 205  *                 | HT_HASH(ht, -1)             |
 206  *                 +-----------------------------+
 207  * ht->arData ---> | Bucket[0]                   |
 208  *                 | ...                         |
 209  *                 | Bucket[ht->nTableSize-1]    |
 210  *                 +=============================+
 211  */
 212 
 213 #define HT_INVALID_IDX ((uint32_t) -1)
 214 
 215 #define HT_MIN_MASK ((uint32_t) -2)
 216 #define HT_MIN_SIZE 8
 217 
 218 #if SIZEOF_SIZE_T == 4
 219 # define HT_MAX_SIZE 0x04000000 /* small enough to avoid overflow checks */
 220 # define HT_HASH_TO_BUCKET_EX(data, idx) \
 221         ((Bucket*)((char*)(data) + (idx)))
 222 # define HT_IDX_TO_HASH(idx) \
 223         ((idx) * sizeof(Bucket))
 224 # define HT_HASH_TO_IDX(idx) \
 225         ((idx) / sizeof(Bucket))
 226 #elif SIZEOF_SIZE_T == 8
 227 # define HT_MAX_SIZE 0x80000000
 228 # define HT_HASH_TO_BUCKET_EX(data, idx) \
 229         ((data) + (idx))
 230 # define HT_IDX_TO_HASH(idx) \
 231         (idx)
 232 # define HT_HASH_TO_IDX(idx) \
 233         (idx)
 234 #else
 235 # error "Unknown SIZEOF_SIZE_T"
 236 #endif
 237 
 238 #define HT_HASH_EX(data, idx) \
 239         ((uint32_t*)(data))[(int32_t)(idx)]
 240 #define HT_HASH(ht, idx) \
 241         HT_HASH_EX((ht)->arData, idx)
 242 
 243 #define HT_HASH_SIZE(nTableMask) \
 244         (((size_t)(uint32_t)-(int32_t)(nTableMask)) * sizeof(uint32_t))
 245 #define HT_DATA_SIZE(nTableSize) \
 246         ((size_t)(nTableSize) * sizeof(Bucket))
 247 #define HT_SIZE_EX(nTableSize, nTableMask) \
 248         (HT_DATA_SIZE((nTableSize)) + HT_HASH_SIZE((nTableMask)))
 249 #define HT_SIZE(ht) \
 250         HT_SIZE_EX((ht)->nTableSize, (ht)->nTableMask)
 251 #define HT_USED_SIZE(ht) \
 252         (HT_HASH_SIZE((ht)->nTableMask) + ((size_t)(ht)->nNumUsed * sizeof(Bucket)))
 253 #define HT_HASH_RESET(ht) \
 254         memset(&HT_HASH(ht, (ht)->nTableMask), HT_INVALID_IDX, HT_HASH_SIZE((ht)->nTableMask))
 255 #define HT_HASH_RESET_PACKED(ht) do { \
 256                 HT_HASH(ht, -2) = HT_INVALID_IDX; \
 257                 HT_HASH(ht, -1) = HT_INVALID_IDX; \
 258         } while (0)
 259 #define HT_HASH_TO_BUCKET(ht, idx) \
 260         HT_HASH_TO_BUCKET_EX((ht)->arData, idx)
 261 
 262 #define HT_SET_DATA_ADDR(ht, ptr) do { \
 263                 (ht)->arData = (Bucket*)(((char*)(ptr)) + HT_HASH_SIZE((ht)->nTableMask)); \
 264         } while (0)
 265 #define HT_GET_DATA_ADDR(ht) \
 266         ((char*)((ht)->arData) - HT_HASH_SIZE((ht)->nTableMask))
 267 
 268 typedef uint32_t HashPosition;
 269 
 270 typedef struct _HashTableIterator {
 271         HashTable    *ht;
 272         HashPosition  pos;
 273 } HashTableIterator;
 274 
 275 struct _zend_object {
 276         zend_refcounted_h gc;
 277         uint32_t          handle;
 278         zend_class_entry *ce;
 279         const zend_object_handlers *handlers;
 280         HashTable        *properties;
 281         zval              properties_table[1];
 282 };
 283 
 284 struct _zend_resource {
 285         zend_refcounted_h gc;
 286         int               handle;
 287         int               type;
 288         void             *ptr;
 289 };
 290 
 291 struct _zend_reference {
 292         zend_refcounted_h gc;
 293         zval              val;
 294 };
 295 
 296 struct _zend_ast_ref {
 297         zend_refcounted_h gc;
 298         zend_ast         *ast;
 299 };
 300 
 301 /* regular data types */
 302 #define IS_UNDEF                                        0
 303 #define IS_NULL                                         1
 304 #define IS_FALSE                                        2
 305 #define IS_TRUE                                         3
 306 #define IS_LONG                                         4
 307 #define IS_DOUBLE                                       5
 308 #define IS_STRING                                       6
 309 #define IS_ARRAY                                        7
 310 #define IS_OBJECT                                       8
 311 #define IS_RESOURCE                                     9
 312 #define IS_REFERENCE                            10
 313 
 314 /* constant expressions */
 315 #define IS_CONSTANT                                     11
 316 #define IS_CONSTANT_AST                         12
 317 
 318 /* fake types */
 319 #define _IS_BOOL                                        13
 320 #define IS_CALLABLE                                     14
 321 
 322 /* internal types */
 323 #define IS_INDIRECT                     15
 324 #define IS_PTR                                          17
 325 
 326 static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 327         return pz->u1.v.type;
 328 }
 329 
 330 #define ZEND_SAME_FAKE_TYPE(faketype, realtype) ( \
 331         (faketype) == (realtype) \
 332         || ((faketype) == _IS_BOOL && ((realtype) == IS_TRUE || (realtype) == IS_FALSE)) \
 333 )
 334 
 335 /* we should never set just Z_TYPE, we should set Z_TYPE_INFO */
 336 #define Z_TYPE(zval)                            zval_get_type(&(zval))
 337 #define Z_TYPE_P(zval_p)                        Z_TYPE(*(zval_p))
 338 
 339 #define Z_TYPE_FLAGS(zval)                      (zval).u1.v.type_flags
 340 #define Z_TYPE_FLAGS_P(zval_p)          Z_TYPE_FLAGS(*(zval_p))
 341 
 342 #define Z_CONST_FLAGS(zval)                     (zval).u1.v.const_flags
 343 #define Z_CONST_FLAGS_P(zval_p)         Z_CONST_FLAGS(*(zval_p))
 344 
 345 #define Z_VAR_FLAGS(zval)                       (zval).u2.var_flags
 346 #define Z_VAR_FLAGS_P(zval_p)           Z_VAR_FLAGS(*(zval_p))
 347 
 348 #define Z_TYPE_INFO(zval)                       (zval).u1.type_info
 349 #define Z_TYPE_INFO_P(zval_p)           Z_TYPE_INFO(*(zval_p))
 350 
 351 #define Z_NEXT(zval)                            (zval).u2.next
 352 #define Z_NEXT_P(zval_p)                        Z_NEXT(*(zval_p))
 353 
 354 #define Z_CACHE_SLOT(zval)                      (zval).u2.cache_slot
 355 #define Z_CACHE_SLOT_P(zval_p)          Z_CACHE_SLOT(*(zval_p))
 356 
 357 #define Z_FE_POS(zval)                          (zval).u2.fe_pos
 358 #define Z_FE_POS_P(zval_p)                      Z_FE_POS(*(zval_p))
 359 
 360 #define Z_FE_ITER(zval)                         (zval).u2.fe_iter_idx
 361 #define Z_FE_ITER_P(zval_p)                     Z_FE_ITER(*(zval_p))
 362 
 363 #define Z_COUNTED(zval)                         (zval).value.counted
 364 #define Z_COUNTED_P(zval_p)                     Z_COUNTED(*(zval_p))
 365 
 366 #define Z_TYPE_MASK                                     0xff
 367 
 368 #define Z_TYPE_FLAGS_SHIFT                      8
 369 #define Z_CONST_FLAGS_SHIFT                     16
 370 
 371 #define GC_REFCOUNT(p)                          (p)->gc.refcount
 372 #define GC_TYPE(p)                                      (p)->gc.u.v.type
 373 #define GC_FLAGS(p)                                     (p)->gc.u.v.flags
 374 #define GC_INFO(p)                                      (p)->gc.u.v.gc_info
 375 #define GC_TYPE_INFO(p)                         (p)->gc.u.type_info
 376 
 377 #define Z_GC_TYPE(zval)                         GC_TYPE(Z_COUNTED(zval))
 378 #define Z_GC_TYPE_P(zval_p)                     Z_GC_TYPE(*(zval_p))
 379 
 380 #define Z_GC_FLAGS(zval)                        GC_FLAGS(Z_COUNTED(zval))
 381 #define Z_GC_FLAGS_P(zval_p)            Z_GC_FLAGS(*(zval_p))
 382 
 383 #define Z_GC_INFO(zval)                         GC_INFO(Z_COUNTED(zval))
 384 #define Z_GC_INFO_P(zval_p)                     Z_GC_INFO(*(zval_p))
 385 
 386 #define Z_GC_TYPE_INFO(zval)            GC_TYPE_INFO(Z_COUNTED(zval))
 387 #define Z_GC_TYPE_INFO_P(zval_p)        Z_GC_TYPE_INFO(*(zval_p))
 388 
 389 /* zval.u1.v.type_flags */
 390 #define IS_TYPE_CONSTANT                        (1<<0)
 391 #define IS_TYPE_IMMUTABLE                       (1<<1)
 392 #define IS_TYPE_REFCOUNTED                      (1<<2)
 393 #define IS_TYPE_COLLECTABLE                     (1<<3)
 394 #define IS_TYPE_COPYABLE                        (1<<4)
 395 #define IS_TYPE_SYMBOLTABLE                     (1<<5)
 396 
 397 /* extended types */
 398 #define IS_INTERNED_STRING_EX           IS_STRING
 399 
 400 #define IS_STRING_EX                            (IS_STRING         | ((                   IS_TYPE_REFCOUNTED |                       IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 401 #define IS_ARRAY_EX                                     (IS_ARRAY          | ((                   IS_TYPE_REFCOUNTED | IS_TYPE_COLLECTABLE | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 402 #define IS_OBJECT_EX                            (IS_OBJECT         | ((                   IS_TYPE_REFCOUNTED | IS_TYPE_COLLECTABLE                   ) << Z_TYPE_FLAGS_SHIFT))
 403 #define IS_RESOURCE_EX                          (IS_RESOURCE       | ((                   IS_TYPE_REFCOUNTED                                         ) << Z_TYPE_FLAGS_SHIFT))
 404 #define IS_REFERENCE_EX                         (IS_REFERENCE      | ((                   IS_TYPE_REFCOUNTED                                         ) << Z_TYPE_FLAGS_SHIFT))
 405 
 406 #define IS_CONSTANT_EX                          (IS_CONSTANT       | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED |                       IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 407 #define IS_CONSTANT_AST_EX                      (IS_CONSTANT_AST   | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED |                       IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 408 
 409 /* zval.u1.v.const_flags */
 410 #define IS_CONSTANT_UNQUALIFIED         0x010
 411 #define IS_LEXICAL_VAR                          0x020
 412 #define IS_LEXICAL_REF                          0x040
 413 #define IS_CONSTANT_CLASS           0x080  /* __CLASS__ in trait */
 414 #define IS_CONSTANT_IN_NAMESPACE        0x100  /* used only in opline->extended_value */
 415 
 416 /* zval.u2.var_flags */
 417 #define IS_VAR_RET_REF                          (1<<0) /* return by by reference */
 418 
 419 /* string flags (zval.value->gc.u.flags) */
 420 #define IS_STR_PERSISTENT                       (1<<0) /* allocated using malloc   */
 421 #define IS_STR_INTERNED                         (1<<1) /* interned string          */
 422 #define IS_STR_PERMANENT                (1<<2) /* relives request boundary */
 423 
 424 #define IS_STR_CONSTANT             (1<<3) /* constant index */
 425 #define IS_STR_CONSTANT_UNQUALIFIED (1<<4) /* the same as IS_CONSTANT_UNQUALIFIED */
 426 
 427 /* array flags */
 428 #define IS_ARRAY_IMMUTABLE                      (1<<1) /* the same as IS_TYPE_IMMUTABLE */
 429 
 430 /* object flags (zval.value->gc.u.flags) */
 431 #define IS_OBJ_APPLY_COUNT                      0x07
 432 #define IS_OBJ_DESTRUCTOR_CALLED        (1<<3)
 433 #define IS_OBJ_FREE_CALLED                      (1<<4)
 434 #define IS_OBJ_USE_GUARDS           (1<<5)
 435 #define IS_OBJ_HAS_GUARDS           (1<<6)
 436 
 437 #define Z_OBJ_APPLY_COUNT(zval) \
 438         (Z_GC_FLAGS(zval) & IS_OBJ_APPLY_COUNT)
 439 
 440 #define Z_OBJ_INC_APPLY_COUNT(zval) do { \
 441                 Z_GC_FLAGS(zval) = \
 442                         (Z_GC_FLAGS(zval) & ~IS_OBJ_APPLY_COUNT) | \
 443                         ((Z_GC_FLAGS(zval) & IS_OBJ_APPLY_COUNT) + 1); \
 444         } while (0)
 445 
 446 #define Z_OBJ_DEC_APPLY_COUNT(zval) do { \
 447                 Z_GC_FLAGS(zval) = \
 448                         (Z_GC_FLAGS(zval) & ~IS_OBJ_APPLY_COUNT) | \
 449                         ((Z_GC_FLAGS(zval) & IS_OBJ_APPLY_COUNT) - 1); \
 450         } while (0)
 451 
 452 #define Z_OBJ_APPLY_COUNT_P(zv)     Z_OBJ_APPLY_COUNT(*(zv))
 453 #define Z_OBJ_INC_APPLY_COUNT_P(zv) Z_OBJ_INC_APPLY_COUNT(*(zv))
 454 #define Z_OBJ_DEC_APPLY_COUNT_P(zv) Z_OBJ_DEC_APPLY_COUNT(*(zv))
 455 
 456 /* All data types < IS_STRING have their constructor/destructors skipped */
 457 #define Z_CONSTANT(zval)                        ((Z_TYPE_FLAGS(zval) & IS_TYPE_CONSTANT) != 0)
 458 #define Z_CONSTANT_P(zval_p)            Z_CONSTANT(*(zval_p))
 459 
 460 #define Z_REFCOUNTED(zval)                      ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0)
 461 #define Z_REFCOUNTED_P(zval_p)          Z_REFCOUNTED(*(zval_p))
 462 
 463 #define Z_COLLECTABLE(zval)                     ((Z_TYPE_FLAGS(zval) & IS_TYPE_COLLECTABLE) != 0)
 464 #define Z_COLLECTABLE_P(zval_p)         Z_COLLECTABLE(*(zval_p))
 465 
 466 #define Z_COPYABLE(zval)                        ((Z_TYPE_FLAGS(zval) & IS_TYPE_COPYABLE) != 0)
 467 #define Z_COPYABLE_P(zval_p)            Z_COPYABLE(*(zval_p))
 468 
 469 #define Z_IMMUTABLE(zval)                       ((Z_TYPE_FLAGS(zval) & IS_TYPE_IMMUTABLE) != 0)
 470 #define Z_IMMUTABLE_P(zval_p)           Z_IMMUTABLE(*(zval_p))
 471 
 472 #define Z_SYMBOLTABLE(zval)                     ((Z_TYPE_FLAGS(zval) & IS_TYPE_SYMBOLTABLE) != 0)
 473 #define Z_SYMBOLTABLE_P(zval_p)         Z_SYMBOLTABLE(*(zval_p))
 474 
 475 /* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
 476 #define Z_OPT_TYPE(zval)                        (Z_TYPE_INFO(zval) & Z_TYPE_MASK)
 477 #define Z_OPT_TYPE_P(zval_p)            Z_OPT_TYPE(*(zval_p))
 478 
 479 #define Z_OPT_CONSTANT(zval)            ((Z_TYPE_INFO(zval) & (IS_TYPE_CONSTANT << Z_TYPE_FLAGS_SHIFT)) != 0)
 480 #define Z_OPT_CONSTANT_P(zval_p)        Z_OPT_CONSTANT(*(zval_p))
 481 
 482 #define Z_OPT_REFCOUNTED(zval)          ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)
 483 #define Z_OPT_REFCOUNTED_P(zval_p)      Z_OPT_REFCOUNTED(*(zval_p))
 484 
 485 #define Z_OPT_COLLECTABLE(zval)         ((Z_TYPE_INFO(zval) & (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
 486 #define Z_OPT_COLLECTABLE_P(zval_p)     Z_OPT_COLLECTABLE(*(zval_p))
 487 
 488 #define Z_OPT_COPYABLE(zval)            ((Z_TYPE_INFO(zval) & (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
 489 #define Z_OPT_COPYABLE_P(zval_p)        Z_OPT_COPYABLE(*(zval_p))
 490 
 491 #define Z_OPT_IMMUTABLE(zval)           ((Z_TYPE_INFO(zval) & (IS_TYPE_IMMUTABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
 492 #define Z_OPT_IMMUTABLE_P(zval_p)       Z_OPT_IMMUTABLE(*(zval_p))
 493 
 494 #define Z_OPT_ISREF(zval)                       (Z_OPT_TYPE(zval) == IS_REFERENCE)
 495 #define Z_OPT_ISREF_P(zval_p)           Z_OPT_ISREF(*(zval_p))
 496 
 497 #define Z_ISREF(zval)                           (Z_TYPE(zval) == IS_REFERENCE)
 498 #define Z_ISREF_P(zval_p)                       Z_ISREF(*(zval_p))
 499 
 500 #define Z_ISUNDEF(zval)                         (Z_TYPE(zval) == IS_UNDEF)
 501 #define Z_ISUNDEF_P(zval_p)                     Z_ISUNDEF(*(zval_p))
 502 
 503 #define Z_ISNULL(zval)                          (Z_TYPE(zval) == IS_NULL)
 504 #define Z_ISNULL_P(zval_p)                      Z_ISNULL(*(zval_p))
 505 
 506 #define Z_LVAL(zval)                            (zval).value.lval
 507 #define Z_LVAL_P(zval_p)                        Z_LVAL(*(zval_p))
 508 
 509 #define Z_DVAL(zval)                            (zval).value.dval
 510 #define Z_DVAL_P(zval_p)                        Z_DVAL(*(zval_p))
 511 
 512 #define Z_STR(zval)                                     (zval).value.str
 513 #define Z_STR_P(zval_p)                         Z_STR(*(zval_p))
 514 
 515 #define Z_STRVAL(zval)                          ZSTR_VAL(Z_STR(zval))
 516 #define Z_STRVAL_P(zval_p)                      Z_STRVAL(*(zval_p))
 517 
 518 #define Z_STRLEN(zval)                          ZSTR_LEN(Z_STR(zval))
 519 #define Z_STRLEN_P(zval_p)                      Z_STRLEN(*(zval_p))
 520 
 521 #define Z_STRHASH(zval)                         ZSTR_HASH(Z_STR(zval))
 522 #define Z_STRHASH_P(zval_p)                     Z_STRHASH(*(zval_p))
 523 
 524 #define Z_ARR(zval)                                     (zval).value.arr
 525 #define Z_ARR_P(zval_p)                         Z_ARR(*(zval_p))
 526 
 527 #define Z_ARRVAL(zval)                          Z_ARR(zval)
 528 #define Z_ARRVAL_P(zval_p)                      Z_ARRVAL(*(zval_p))
 529 
 530 #define Z_OBJ(zval)                                     (zval).value.obj
 531 #define Z_OBJ_P(zval_p)                         Z_OBJ(*(zval_p))
 532 
 533 #define Z_OBJ_HT(zval)                          Z_OBJ(zval)->handlers
 534 #define Z_OBJ_HT_P(zval_p)                      Z_OBJ_HT(*(zval_p))
 535 
 536 #define Z_OBJ_HANDLER(zval, hf)         Z_OBJ_HT((zval))->hf
 537 #define Z_OBJ_HANDLER_P(zv_p, hf)       Z_OBJ_HANDLER(*(zv_p), hf)
 538 
 539 #define Z_OBJ_HANDLE(zval)          (Z_OBJ((zval)))->handle
 540 #define Z_OBJ_HANDLE_P(zval_p)      Z_OBJ_HANDLE(*(zval_p))
 541 
 542 #define Z_OBJCE(zval)                           (Z_OBJ(zval)->ce)
 543 #define Z_OBJCE_P(zval_p)                       Z_OBJCE(*(zval_p))
 544 
 545 #define Z_OBJPROP(zval)                         Z_OBJ_HT((zval))->get_properties(&(zval))
 546 #define Z_OBJPROP_P(zval_p)                     Z_OBJPROP(*(zval_p))
 547 
 548 #define Z_OBJDEBUG(zval,tmp)            (Z_OBJ_HANDLER((zval),get_debug_info)?Z_OBJ_HANDLER((zval),get_debug_info)(&(zval),&tmp):(tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL))
 549 #define Z_OBJDEBUG_P(zval_p,tmp)        Z_OBJDEBUG(*(zval_p), tmp)
 550 
 551 #define Z_RES(zval)                                     (zval).value.res
 552 #define Z_RES_P(zval_p)                         Z_RES(*zval_p)
 553 
 554 #define Z_RES_HANDLE(zval)                      Z_RES(zval)->handle
 555 #define Z_RES_HANDLE_P(zval_p)          Z_RES_HANDLE(*zval_p)
 556 
 557 #define Z_RES_TYPE(zval)                        Z_RES(zval)->type
 558 #define Z_RES_TYPE_P(zval_p)            Z_RES_TYPE(*zval_p)
 559 
 560 #define Z_RES_VAL(zval)                         Z_RES(zval)->ptr
 561 #define Z_RES_VAL_P(zval_p)                     Z_RES_VAL(*zval_p)
 562 
 563 #define Z_REF(zval)                                     (zval).value.ref
 564 #define Z_REF_P(zval_p)                         Z_REF(*(zval_p))
 565 
 566 #define Z_REFVAL(zval)                          &Z_REF(zval)->val
 567 #define Z_REFVAL_P(zval_p)                      Z_REFVAL(*(zval_p))
 568 
 569 #define Z_AST(zval)                                     (zval).value.ast
 570 #define Z_AST_P(zval_p)                         Z_AST(*(zval_p))
 571 
 572 #define Z_ASTVAL(zval)                          (zval).value.ast->ast
 573 #define Z_ASTVAL_P(zval_p)                      Z_ASTVAL(*(zval_p))
 574 
 575 #define Z_INDIRECT(zval)                        (zval).value.zv
 576 #define Z_INDIRECT_P(zval_p)            Z_INDIRECT(*(zval_p))
 577 
 578 #define Z_CE(zval)                                      (zval).value.ce
 579 #define Z_CE_P(zval_p)                          Z_CE(*(zval_p))
 580 
 581 #define Z_FUNC(zval)                            (zval).value.func
 582 #define Z_FUNC_P(zval_p)                        Z_FUNC(*(zval_p))
 583 
 584 #define Z_PTR(zval)                                     (zval).value.ptr
 585 #define Z_PTR_P(zval_p)                         Z_PTR(*(zval_p))
 586 
 587 #define ZVAL_UNDEF(z) do {                              \
 588                 Z_TYPE_INFO_P(z) = IS_UNDEF;    \
 589         } while (0)
 590 
 591 #define ZVAL_NULL(z) do {                               \
 592                 Z_TYPE_INFO_P(z) = IS_NULL;             \
 593         } while (0)
 594 
 595 #define ZVAL_FALSE(z) do {                              \
 596                 Z_TYPE_INFO_P(z) = IS_FALSE;    \
 597         } while (0)
 598 
 599 #define ZVAL_TRUE(z) do {                               \
 600                 Z_TYPE_INFO_P(z) = IS_TRUE;             \
 601         } while (0)
 602 
 603 #define ZVAL_BOOL(z, b) do {                    \
 604                 Z_TYPE_INFO_P(z) =                              \
 605                         (b) ? IS_TRUE : IS_FALSE;       \
 606         } while (0)
 607 
 608 #define ZVAL_LONG(z, l) {                               \
 609                 zval *__z = (z);                                \
 610                 Z_LVAL_P(__z) = l;                              \
 611                 Z_TYPE_INFO_P(__z) = IS_LONG;   \
 612         }
 613 
 614 #define ZVAL_DOUBLE(z, d) {                             \
 615                 zval *__z = (z);                                \
 616                 Z_DVAL_P(__z) = d;                              \
 617                 Z_TYPE_INFO_P(__z) = IS_DOUBLE; \
 618         }
 619 
 620 #define ZVAL_STR(z, s) do {                                             \
 621                 zval *__z = (z);                                                \
 622                 zend_string *__s = (s);                                 \
 623                 Z_STR_P(__z) = __s;                                             \
 624                 /* interned strings support */                  \
 625                 Z_TYPE_INFO_P(__z) = ZSTR_IS_INTERNED(__s) ? \
 626                         IS_INTERNED_STRING_EX :                         \
 627                         IS_STRING_EX;                                           \
 628         } while (0)
 629 
 630 #define ZVAL_INTERNED_STR(z, s) do {                            \
 631                 zval *__z = (z);                                                        \
 632                 zend_string *__s = (s);                                         \
 633                 Z_STR_P(__z) = __s;                                                     \
 634                 Z_TYPE_INFO_P(__z) = IS_INTERNED_STRING_EX;     \
 635         } while (0)
 636 
 637 #define ZVAL_NEW_STR(z, s) do {                                 \
 638                 zval *__z = (z);                                                \
 639                 zend_string *__s = (s);                                 \
 640                 Z_STR_P(__z) = __s;                                             \
 641                 Z_TYPE_INFO_P(__z) = IS_STRING_EX;              \
 642         } while (0)
 643 
 644 #define ZVAL_STR_COPY(z, s) do {                                                \
 645                 zval *__z = (z);                                                                \
 646                 zend_string *__s = (s);                                                 \
 647                 Z_STR_P(__z) = __s;                                                             \
 648                 /* interned strings support */                                  \
 649                 if (ZSTR_IS_INTERNED(__s)) {                                                    \
 650                         Z_TYPE_INFO_P(__z) = IS_INTERNED_STRING_EX;     \
 651                 } else {                                                                                \
 652                         GC_REFCOUNT(__s)++;                                                     \
 653                         Z_TYPE_INFO_P(__z) = IS_STRING_EX;                      \
 654                 }                                                                                               \
 655         } while (0)
 656 
 657 #define ZVAL_ARR(z, a) do {                                             \
 658                 zval *__z = (z);                                                \
 659                 Z_ARR_P(__z) = (a);                                             \
 660                 Z_TYPE_INFO_P(__z) = IS_ARRAY_EX;               \
 661         } while (0)
 662 
 663 #define ZVAL_NEW_ARR(z) do {                                                                    \
 664                 zval *__z = (z);                                                                                \
 665                 zend_array *_arr =                                                                              \
 666                 (zend_array *) emalloc(sizeof(zend_array));                             \
 667                 Z_ARR_P(__z) = _arr;                                                                    \
 668                 Z_TYPE_INFO_P(__z) = IS_ARRAY_EX;                                               \
 669         } while (0)
 670 
 671 #define ZVAL_NEW_PERSISTENT_ARR(z) do {                                                 \
 672                 zval *__z = (z);                                                                                \
 673                 zend_array *_arr =                                                                              \
 674                 (zend_array *) malloc(sizeof(zend_array));                              \
 675                 Z_ARR_P(__z) = _arr;                                                                    \
 676                 Z_TYPE_INFO_P(__z) = IS_ARRAY_EX;                                               \
 677         } while (0)
 678 
 679 #define ZVAL_OBJ(z, o) do {                                             \
 680                 zval *__z = (z);                                                \
 681                 Z_OBJ_P(__z) = (o);                                             \
 682                 Z_TYPE_INFO_P(__z) = IS_OBJECT_EX;              \
 683         } while (0)
 684 
 685 #define ZVAL_RES(z, r) do {                                             \
 686                 zval *__z = (z);                                                \
 687                 Z_RES_P(__z) = (r);                                             \
 688                 Z_TYPE_INFO_P(__z) = IS_RESOURCE_EX;    \
 689         } while (0)
 690 
 691 #define ZVAL_NEW_RES(z, h, p, t) do {                                                   \
 692                 zend_resource *_res =                                                                   \
 693                 (zend_resource *) emalloc(sizeof(zend_resource));               \
 694                 zval *__z;                                                                                              \
 695                 GC_REFCOUNT(_res) = 1;                                                                  \
 696                 GC_TYPE_INFO(_res) = IS_RESOURCE;                                               \
 697                 _res->handle = (h);                                                                             \
 698                 _res->type = (t);                                                                               \
 699                 _res->ptr = (p);                                                                                \
 700                 __z = (z);                                                                                              \
 701                 Z_RES_P(__z) = _res;                                                                    \
 702                 Z_TYPE_INFO_P(__z) = IS_RESOURCE_EX;                                    \
 703         } while (0)
 704 
 705 #define ZVAL_NEW_PERSISTENT_RES(z, h, p, t) do {                                \
 706                 zend_resource *_res =                                                                   \
 707                 (zend_resource *) malloc(sizeof(zend_resource));                \
 708                 zval *__z;                                                                                              \
 709                 GC_REFCOUNT(_res) = 1;                                                                  \
 710                 GC_TYPE_INFO(_res) = IS_RESOURCE;                                               \
 711                 _res->handle = (h);                                                                             \
 712                 _res->type = (t);                                                                               \
 713                 _res->ptr = (p);                                                                                \
 714                 __z = (z);                                                                                              \
 715                 Z_RES_P(__z) = _res;                                                                    \
 716                 Z_TYPE_INFO_P(__z) = IS_RESOURCE_EX;                                    \
 717         } while (0)
 718 
 719 #define ZVAL_REF(z, r) do {                                                                             \
 720                 zval *__z = (z);                                                                                \
 721                 Z_REF_P(__z) = (r);                                                                             \
 722                 Z_TYPE_INFO_P(__z) = IS_REFERENCE_EX;                                   \
 723         } while (0)
 724 
 725 #define ZVAL_NEW_EMPTY_REF(z) do {                                                              \
 726                 zend_reference *_ref =                                                                  \
 727                 (zend_reference *) emalloc(sizeof(zend_reference));             \
 728                 GC_REFCOUNT(_ref) = 1;                                                                  \
 729                 GC_TYPE_INFO(_ref) = IS_REFERENCE;                                              \
 730                 Z_REF_P(z) = _ref;                                                                              \
 731                 Z_TYPE_INFO_P(z) = IS_REFERENCE_EX;                                             \
 732         } while (0)
 733 
 734 #define ZVAL_NEW_REF(z, r) do {                                                                 \
 735                 zend_reference *_ref =                                                                  \
 736                 (zend_reference *) emalloc(sizeof(zend_reference));             \
 737                 GC_REFCOUNT(_ref) = 1;                                                                  \
 738                 GC_TYPE_INFO(_ref) = IS_REFERENCE;                                              \
 739                 ZVAL_COPY_VALUE(&_ref->val, r);                                                 \
 740                 Z_REF_P(z) = _ref;                                                                              \
 741                 Z_TYPE_INFO_P(z) = IS_REFERENCE_EX;                                             \
 742         } while (0)
 743 
 744 #define ZVAL_NEW_PERSISTENT_REF(z, r) do {                                              \
 745                 zend_reference *_ref =                                                                  \
 746                 (zend_reference *) malloc(sizeof(zend_reference));              \
 747                 GC_REFCOUNT(_ref) = 1;                                                                  \
 748                 GC_TYPE_INFO(_ref) = IS_REFERENCE;                                              \
 749                 ZVAL_COPY_VALUE(&_ref->val, r);                                                 \
 750                 Z_REF_P(z) = _ref;                                                                              \
 751                 Z_TYPE_INFO_P(z) = IS_REFERENCE_EX;                                             \
 752         } while (0)
 753 
 754 #define ZVAL_NEW_AST(z, a) do {                                                                 \
 755                 zval *__z = (z);                                                                                \
 756                 zend_ast_ref *_ast =                                                                    \
 757                 (zend_ast_ref *) emalloc(sizeof(zend_ast_ref));                 \
 758                 GC_REFCOUNT(_ast) = 1;                                                                  \
 759                 GC_TYPE_INFO(_ast) = IS_CONSTANT_AST;                                   \
 760                 _ast->ast = (a);                                                                                \
 761                 Z_AST_P(__z) = _ast;                                                                    \
 762                 Z_TYPE_INFO_P(__z) = IS_CONSTANT_AST_EX;                                \
 763         } while (0)
 764 
 765 #define ZVAL_INDIRECT(z, v) do {                                                                \
 766                 Z_INDIRECT_P(z) = (v);                                                                  \
 767                 Z_TYPE_INFO_P(z) = IS_INDIRECT;                                                 \
 768         } while (0)
 769 
 770 #define ZVAL_PTR(z, p) do {                                                                             \
 771                 Z_PTR_P(z) = (p);                                                                               \
 772                 Z_TYPE_INFO_P(z) = IS_PTR;                                                              \
 773         } while (0)
 774 
 775 #define ZVAL_FUNC(z, f) do {                                                                    \
 776                 Z_FUNC_P(z) = (f);                                                                              \
 777                 Z_TYPE_INFO_P(z) = IS_PTR;                                                              \
 778         } while (0)
 779 
 780 #define ZVAL_CE(z, c) do {                                                                              \
 781                 Z_CE_P(z) = (c);                                                                                \
 782                 Z_TYPE_INFO_P(z) = IS_PTR;                                                              \
 783         } while (0)
 784 
 785 #define Z_REFCOUNT_P(pz)                        zval_refcount_p(pz)
 786 #define Z_SET_REFCOUNT_P(pz, rc)        zval_set_refcount_p(pz, rc)
 787 #define Z_ADDREF_P(pz)                          zval_addref_p(pz)
 788 #define Z_DELREF_P(pz)                          zval_delref_p(pz)
 789 
 790 #define Z_REFCOUNT(z)                           Z_REFCOUNT_P(&(z))
 791 #define Z_SET_REFCOUNT(z, rc)           Z_SET_REFCOUNT_P(&(z), rc)
 792 #define Z_ADDREF(z)                                     Z_ADDREF_P(&(z))
 793 #define Z_DELREF(z)                                     Z_DELREF_P(&(z))
 794 
 795 #define Z_TRY_ADDREF_P(pz) do {         \
 796         if (Z_REFCOUNTED_P((pz))) {             \
 797                 Z_ADDREF_P((pz));                       \
 798         }                                                               \
 799 } while (0)
 800 
 801 #define Z_TRY_DELREF_P(pz) do {         \
 802         if (Z_REFCOUNTED_P((pz))) {             \
 803                 Z_DELREF_P((pz));                       \
 804         }                                                               \
 805 } while (0)
 806 
 807 #define Z_TRY_ADDREF(z)                         Z_TRY_ADDREF_P(&(z))
 808 #define Z_TRY_DELREF(z)                         Z_TRY_DELREF_P(&(z))
 809 
 810 static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
 811         ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz) || Z_SYMBOLTABLE_P(pz));
 812         return GC_REFCOUNT(Z_COUNTED_P(pz));
 813 }
 814 
 815 static zend_always_inline uint32_t zval_set_refcount_p(zval* pz, uint32_t rc) {
 816         ZEND_ASSERT(Z_REFCOUNTED_P(pz));
 817         return GC_REFCOUNT(Z_COUNTED_P(pz)) = rc;
 818 }
 819 
 820 static zend_always_inline uint32_t zval_addref_p(zval* pz) {
 821         ZEND_ASSERT(Z_REFCOUNTED_P(pz));
 822         return ++GC_REFCOUNT(Z_COUNTED_P(pz));
 823 }
 824 
 825 static zend_always_inline uint32_t zval_delref_p(zval* pz) {
 826         ZEND_ASSERT(Z_REFCOUNTED_P(pz));
 827         return --GC_REFCOUNT(Z_COUNTED_P(pz));
 828 }
 829 
 830 #if SIZEOF_SIZE_T == 4
 831 # define ZVAL_COPY_VALUE_EX(z, v, gc, t)                                \
 832         do {                                                                                            \
 833                 uint32_t _w2 = v->value.ww.w2;                                  \
 834                 Z_COUNTED_P(z) = gc;                                                    \
 835                 z->value.ww.w2 = _w2;                                                   \
 836                 Z_TYPE_INFO_P(z) = t;                                                   \
 837         } while (0)
 838 #elif SIZEOF_SIZE_T == 8
 839 # define ZVAL_COPY_VALUE_EX(z, v, gc, t)                                \
 840         do {                                                                                            \
 841                 Z_COUNTED_P(z) = gc;                                                    \
 842                 Z_TYPE_INFO_P(z) = t;                                                   \
 843         } while (0)
 844 #else
 845 # error "Unknown SIZEOF_SIZE_T"
 846 #endif
 847 
 848 #define ZVAL_COPY_VALUE(z, v)                                                   \
 849         do {                                                                                            \
 850                 zval *_z1 = (z);                                                                \
 851                 const zval *_z2 = (v);                                                  \
 852                 zend_refcounted *_gc = Z_COUNTED_P(_z2);                \
 853                 uint32_t _t = Z_TYPE_INFO_P(_z2);                               \
 854                 ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);                  \
 855         } while (0)
 856 
 857 #define ZVAL_COPY(z, v)                                                                 \
 858         do {                                                                                            \
 859                 zval *_z1 = (z);                                                                \
 860                 const zval *_z2 = (v);                                                  \
 861                 zend_refcounted *_gc = Z_COUNTED_P(_z2);                \
 862                 uint32_t _t = Z_TYPE_INFO_P(_z2);                               \
 863                 ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);                  \
 864                 if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \
 865                         GC_REFCOUNT(_gc)++;                                                     \
 866                 }                                                                                               \
 867         } while (0)
 868 
 869 #define ZVAL_DUP(z, v)                                                                  \
 870         do {                                                                                            \
 871                 zval *_z1 = (z);                                                                \
 872                 const zval *_z2 = (v);                                                  \
 873                 zend_refcounted *_gc = Z_COUNTED_P(_z2);                \
 874                 uint32_t _t = Z_TYPE_INFO_P(_z2);                               \
 875                 ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);                  \
 876                 if ((_t & ((IS_TYPE_REFCOUNTED|IS_TYPE_IMMUTABLE) << Z_TYPE_FLAGS_SHIFT)) != 0) { \
 877                         if ((_t & ((IS_TYPE_COPYABLE|IS_TYPE_IMMUTABLE) << Z_TYPE_FLAGS_SHIFT)) != 0) { \
 878                                 _zval_copy_ctor_func(_z1 ZEND_FILE_LINE_CC); \
 879                         } else {                                                                        \
 880                                 GC_REFCOUNT(_gc)++;                                             \
 881                         }                                                                                       \
 882                 }                                                                                               \
 883         } while (0)
 884 
 885 #define ZVAL_DEREF(z) do {                                                              \
 886                 if (UNEXPECTED(Z_ISREF_P(z))) {                                 \
 887                         (z) = Z_REFVAL_P(z);                                            \
 888                 }                                                                                               \
 889         } while (0)
 890 
 891 #define ZVAL_OPT_DEREF(z) do {                                                  \
 892                 if (UNEXPECTED(Z_OPT_ISREF_P(z))) {                             \
 893                         (z) = Z_REFVAL_P(z);                                            \
 894                 }                                                                                               \
 895         } while (0)
 896 
 897 #define ZVAL_MAKE_REF(zv) do {                                                  \
 898                 zval *__zv = (zv);                                                              \
 899                 if (!Z_ISREF_P(__zv)) {                                                 \
 900                         ZVAL_NEW_REF(__zv, __zv);                                       \
 901                 }                                                                                               \
 902         } while (0)
 903 
 904 #define ZVAL_UNREF(z) do {                                                              \
 905                 zval *_z = (z);                                                                 \
 906                 zend_reference *ref;                                                    \
 907                 ZEND_ASSERT(Z_ISREF_P(_z));                                             \
 908                 ref = Z_REF_P(_z);                                                              \
 909                 ZVAL_COPY_VALUE(_z, &ref->val);                                 \
 910                 efree_size(ref, sizeof(zend_reference));                \
 911         } while (0)
 912 
 913 #define SEPARATE_STRING(zv) do {                                                \
 914                 zval *_zv = (zv);                                                               \
 915                 if (Z_REFCOUNTED_P(_zv) &&                                              \
 916                     Z_REFCOUNT_P(_zv) > 1) {                                    \
 917                         Z_DELREF_P(_zv);                                                        \
 918                         zval_copy_ctor_func(_zv);                                       \
 919                 }                                                                                               \
 920         } while (0)
 921 
 922 #define SEPARATE_ARRAY(zv) do {                                                 \
 923                 zval *_zv = (zv);                                                               \
 924                 zend_array *_arr = Z_ARR_P(_zv);                                \
 925                 if (GC_REFCOUNT(_arr) > 1) {                                    \
 926                         if (!Z_IMMUTABLE_P(_zv)) {                                      \
 927                                 GC_REFCOUNT(_arr)--;                                    \
 928                         }                                                                                       \
 929                         ZVAL_ARR(_zv, zend_array_dup(_arr));            \
 930                 }                                                                                               \
 931         } while (0)
 932 
 933 #define SEPARATE_ZVAL_NOREF(zv) do {                                    \
 934                 zval *_zv = (zv);                                                               \
 935                 ZEND_ASSERT(Z_TYPE_P(_zv) != IS_REFERENCE);             \
 936                 if (Z_COPYABLE_P(_zv) ||                                                \
 937                     Z_IMMUTABLE_P(_zv)) {                                               \
 938                         if (Z_REFCOUNT_P(_zv) > 1) {                            \
 939                                 if (!Z_IMMUTABLE_P(_zv)) {                              \
 940                                         Z_DELREF_P(_zv);                                        \
 941                                 }                                                                               \
 942                                 zval_copy_ctor_func(_zv);                               \
 943                         }                                                                                       \
 944                 }                                                                                               \
 945         } while (0)
 946 
 947 #define SEPARATE_ZVAL(zv) do {                                                  \
 948                 zval *_zv = (zv);                                                               \
 949                 if (Z_REFCOUNTED_P(_zv) ||                                              \
 950                     Z_IMMUTABLE_P(_zv)) {                                               \
 951                         if (Z_REFCOUNT_P(_zv) > 1) {                            \
 952                                 if (Z_COPYABLE_P(_zv) ||                                \
 953                                     Z_IMMUTABLE_P(_zv)) {                               \
 954                                         if (!Z_IMMUTABLE_P(_zv)) {                      \
 955                                                 Z_DELREF_P(_zv);                                \
 956                                         }                                                                       \
 957                                         zval_copy_ctor_func(_zv);                       \
 958                                 } else if (Z_ISREF_P(_zv)) {                    \
 959                                         Z_DELREF_P(_zv);                                        \
 960                                         ZVAL_DUP(_zv, Z_REFVAL_P(_zv));         \
 961                                 }                                                                               \
 962                         }                                                                                       \
 963                 }                                                                                               \
 964         } while (0)
 965 
 966 #define SEPARATE_ZVAL_IF_NOT_REF(zv) do {                               \
 967                 zval *_zv = (zv);                                                               \
 968                 if (Z_COPYABLE_P(_zv) ||                        \
 969                     Z_IMMUTABLE_P(_zv)) {                                               \
 970                         if (Z_REFCOUNT_P(_zv) > 1) {                            \
 971                                 if (!Z_IMMUTABLE_P(_zv)) {                              \
 972                                         Z_DELREF_P(_zv);                                        \
 973                                 }                                                                               \
 974                                 zval_copy_ctor_func(_zv);                               \
 975                         }                                                                                       \
 976                 }                                                                                               \
 977         } while (0)
 978 
 979 #define SEPARATE_ARG_IF_REF(varptr) do {                                \
 980                 ZVAL_DEREF(varptr);                                                             \
 981                 if (Z_REFCOUNTED_P(varptr)) {                                   \
 982                         Z_ADDREF_P(varptr);                                             \
 983                 }                                                                                               \
 984         } while (0)
 985 
 986 #endif /* ZEND_TYPES_H */
 987 
 988 /*
 989  * Local variables:
 990  * tab-width: 4
 991  * c-basic-offset: 4
 992  * indent-tabs-mode: t
 993  * End:
 994  */

/* [<][>][^][v][top][bottom][index][help] */