]> granicus.if.org Git - php/commitdiff
Get rid of IS_TYPE_COPYABLE.
authorDmitry Stogov <dmitry@zend.com>
Fri, 19 Jan 2018 14:47:26 +0000 (17:47 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 19 Jan 2018 14:47:26 +0000 (17:47 +0300)
UPGRADING.INTERNALS
Zend/zend.c
Zend/zend_hash.h
Zend/zend_types.h
Zend/zend_variables.h
ext/opcache/zend_persist.c

index 19eeacc57eeaf28b5a44744c40bd22108409d307..69e073a4d3bdf555c00b49210cf6adc8ddfc8ec6 100644 (file)
@@ -103,10 +103,12 @@ PHP 7.3 INTERNALS UPGRADE NOTES
 
   m. zend_cpu_supports() determines if a feature is supported by current cpu.
 
-  n. IS_STRING zvals don't set IS_TYPE_COPYALE anymore. This prevents string
+  n. IS_TYPE_COPYABLE flag is removed. IS_STRING zvals didn't need to be
      duplication by zval_copy_ctor(), ZVAL_DUP() and SEPARATE_ZVAL*() macros.
      Interned strings didn't set IS_TYPE_COPYALE, so they aren't affected at
-     all.
+     all. Now instead of checking for IS_TYPE_COPYABLE, engine checks for
+     IS_ARRAY type (it may be IS_TYPE_REFCOUNTED or not). All the related
+     macros: Z_COPYABLE..., Z_IMMUTABLE... are kept for compatibility.
 
 ========================
 2. Build system changes
index f42a9875426bbdc3d5e958f9e7cae54353034d77..a915de1b3e1eef43ca424103ef0b9feca65ed6d5 100644 (file)
@@ -732,9 +732,9 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
 {
        zval globals;
 
-       /* IS_TYPE_COPYABLE, but with ref-counter 1 and not IS_TYPE_REFCOUNTED */
+       /* IS_ARRAY, but with ref-counter 1 and not IS_TYPE_REFCOUNTED */
        ZVAL_ARR(&globals, &EG(symbol_table));
-       Z_TYPE_FLAGS_P(&globals) = IS_TYPE_COPYABLE;
+       Z_TYPE_FLAGS_P(&globals) = 0;
        ZVAL_NEW_REF(&globals, &globals);
        zend_hash_update(&EG(symbol_table), name, &globals);
        return 0;
index 312b7d30e8af76a1f3c4d2eeeeeabc7ce5cb9c0e..3c9e22cb85ef5bc2db7dbe90e0ba7707b16b5a3f 100644 (file)
@@ -61,7 +61,7 @@ extern ZEND_API const HashTable zend_empty_array;
 #define ZVAL_EMPTY_ARRAY(z) do {                                               \
                zval *__z = (z);                                                                \
                Z_ARR_P(__z) = (zend_array*)&zend_empty_array;  \
-               Z_TYPE_INFO_P(__z) = IS_ARRAY | (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT); \
+               Z_TYPE_INFO_P(__z) = IS_ARRAY; \
        } while (0)
 
 
index 24f20913c22880ef6a3041e867296e31023f1238..ef1b83a11c9f431d7fe92e2c61583239d5851d18 100644 (file)
@@ -470,19 +470,18 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define GC_OBJECT                                      (IS_OBJECT         | (GC_COLLECTABLE << GC_FLAGS_SHIFT))
 
 /* zval.u1.v.type_flags */
-#define IS_TYPE_COPYABLE                       (1<<1)
 #define IS_TYPE_REFCOUNTED                     (1<<2) /* equal to ZEND_CALL_FREE_EXTRA_ARGS */
 
 /* extended types */
 #define IS_INTERNED_STRING_EX          IS_STRING
 
-#define IS_STRING_EX                           (IS_STRING         | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
-#define IS_ARRAY_EX                                    (IS_ARRAY          | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
-#define IS_OBJECT_EX                           (IS_OBJECT         | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
-#define IS_RESOURCE_EX                         (IS_RESOURCE       | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
-#define IS_REFERENCE_EX                                (IS_REFERENCE      | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
+#define IS_STRING_EX                           (IS_STRING         | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
+#define IS_ARRAY_EX                                    (IS_ARRAY          | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
+#define IS_OBJECT_EX                           (IS_OBJECT         | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
+#define IS_RESOURCE_EX                         (IS_RESOURCE       | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
+#define IS_REFERENCE_EX                                (IS_REFERENCE      | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
 
-#define IS_CONSTANT_AST_EX                     (IS_CONSTANT_AST   | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
+#define IS_CONSTANT_AST_EX                     (IS_CONSTANT_AST   | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT))
 
 /* string flags (zval.value->gc.u.flags) */
 #define IS_STR_INTERNED                                GC_IMMUTABLE  /* interned string */
@@ -525,11 +524,12 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_REFCOUNTED(zval)                     ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0)
 #define Z_REFCOUNTED_P(zval_p)         Z_REFCOUNTED(*(zval_p))
 
-#define Z_COPYABLE(zval)                       ((Z_TYPE_FLAGS(zval) & IS_TYPE_COPYABLE) != 0)
+/* deprecated: (COPYABLE is the same as IS_ARRAY) */
+#define Z_COPYABLE(zval)                       ((Z_TYPE(zval) == IS_ARRAY)
 #define Z_COPYABLE_P(zval_p)           Z_COPYABLE(*(zval_p))
 
-/* deprecated: (IMMUTABLE is the same as COPYABLE && !REFCOUED) */
-#define Z_IMMUTABLE(zval)                      ((Z_TYPE_FLAGS(zval) & (IS_TYPE_REFCOUNTED|IS_TYPE_COPYABLE)) == IS_TYPE_COPYABLE)
+/* deprecated: (IMMUTABLE is the same as IS_ARRAY && !REFCOUED) */
+#define Z_IMMUTABLE(zval)                      ((Z_TYPE_INFO(zval) == IS_ARRAY)
 #define Z_IMMUTABLE_P(zval_p)          Z_IMMUTABLE(*(zval_p))
 #define Z_OPT_IMMUTABLE(zval)          Z_IMMUTABLE(zval_p)
 #define Z_OPT_IMMUTABLE_P(zval_p)      Z_IMMUTABLE(*(zval_p))
@@ -544,7 +544,8 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_OPT_REFCOUNTED(zval)         ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)
 #define Z_OPT_REFCOUNTED_P(zval_p)     Z_OPT_REFCOUNTED(*(zval_p))
 
-#define Z_OPT_COPYABLE(zval)           ((Z_TYPE_INFO(zval) & (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
+/* deprecated: (COPYABLE is the same as IS_ARRAY) */
+#define Z_OPT_COPYABLE(zval)           ((Z_OPT_TYPE(zval) == IS_ARRAY)
 #define Z_OPT_COPYABLE_P(zval_p)       Z_OPT_COPYABLE(*(zval_p))
 
 #define Z_OPT_ISREF(zval)                      (Z_OPT_TYPE(zval) == IS_REFERENCE)
@@ -935,7 +936,9 @@ static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint3
 }
 
 static zend_always_inline uint32_t zval_refcount_p(const zval* pz) {
-       ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_COPYABLE_P(pz));
+#if ZEND_DEBUG
+       ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_TYPE_P(pz) == IS_ARRAY);
+#endif
        return GC_REFCOUNT(Z_COUNTED_P(pz));
 }
 
@@ -999,13 +1002,13 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
                const zval *_z2 = (v);                                                  \
                zend_refcounted *_gc = Z_COUNTED_P(_z2);                \
                uint32_t _t = Z_TYPE_INFO_P(_z2);                               \
-               ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);                  \
-               if ((_t & ((IS_TYPE_REFCOUNTED|IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) != 0) { \
-                       if ((_t & (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT)) != 0) { \
-                               zval_copy_ctor_func(_z1);                               \
-                       } else {                                                                        \
+               if ((_t & Z_TYPE_MASK) == IS_ARRAY) {                   \
+                       ZVAL_ARR(_z1, zend_array_dup((zend_array*)_gc));\
+               } else {                                                                                \
+                       if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \
                                GC_ADDREF(_gc);                                                 \
                        }                                                                                       \
+                       ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);          \
                }                                                                                               \
        } while (0)
 
@@ -1099,12 +1102,12 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
 
 #define SEPARATE_ZVAL_IF_NOT_REF(zv) do {                              \
                zval *__zv = (zv);                                                              \
-               if (Z_COPYABLE_P(__zv)) {                                               \
+               if (Z_TYPE_P(__zv) == IS_ARRAY) {                               \
                        if (Z_REFCOUNT_P(__zv) > 1) {                           \
                                if (Z_REFCOUNTED_P(__zv)) {                             \
                                        Z_DELREF_P(__zv);                                       \
                                }                                                                               \
-                               zval_copy_ctor_func(__zv);                              \
+                               ZVAL_ARR(__zv, zend_array_dup(Z_ARR_P(__zv)));\
                        }                                                                                       \
                }                                                                                               \
        } while (0)
@@ -1122,8 +1125,8 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
                        ZVAL_COPY_VALUE(_zv, &_r->val);                         \
                        if (GC_DELREF(_r) == 0) {                                       \
                                efree_size(_r, sizeof(zend_reference)); \
-                       } else if (Z_OPT_COPYABLE_P(_zv)) {                     \
-                               zval_copy_ctor_func(_zv);                               \
+                       } else if (Z_OPT_TYPE_P(_zv) == IS_ARRAY) {     \
+                               ZVAL_ARR(_zv, zend_array_dup(Z_ARR_P(_zv)));\
                                break;                                                                  \
                        } else if (Z_OPT_REFCOUNTED_P(_zv)) {           \
                                Z_ADDREF_P(_zv);                                                \
index 1f356bd000b0aa7548bf168a92d39ab85aae7464..9be2dc8d483a8dd264de2f7dea2c1a05ccf7b78c 100644 (file)
@@ -55,23 +55,19 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC)
 
 static zend_always_inline void _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
 {
-       if (Z_REFCOUNTED_P(zvalue) || Z_COPYABLE_P(zvalue)) {
-               if (Z_COPYABLE_P(zvalue)) {
-                       _zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
-               } else {
-                       Z_ADDREF_P(zvalue);
-               }
+       if (Z_TYPE_P(zvalue) == IS_ARRAY) {
+               ZVAL_ARR(zvalue, zend_array_dup(Z_ARR_P(zvalue)));
+       } else if (Z_REFCOUNTED_P(zvalue)) {
+               Z_ADDREF_P(zvalue);
        }
 }
 
 static zend_always_inline void _zval_opt_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
 {
-       if (Z_OPT_REFCOUNTED_P(zvalue) || Z_OPT_COPYABLE_P(zvalue)) {
-               if (Z_OPT_COPYABLE_P(zvalue)) {
-                       _zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
-               } else {
-                       Z_ADDREF_P(zvalue);
-               }
+       if (Z_OPT_TYPE_P(zvalue) == IS_ARRAY) {
+               ZVAL_ARR(zvalue, zend_array_dup(Z_ARR_P(zvalue)));
+       } else if (Z_OPT_REFCOUNTED_P(zvalue)) {
+               Z_ADDREF_P(zvalue);
        }
 }
 
index 136255dbef2f475eb24fa1ffc5f5c3320be505ce..010cc9b533c362481c9e6991629b4e18cf574d7f 100644 (file)
@@ -289,7 +289,7 @@ static void zend_persist_zval(zval *z)
                        new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
                        if (new_ptr) {
                                Z_ARR_P(z) = new_ptr;
-                               Z_TYPE_FLAGS_P(z) = IS_TYPE_COPYABLE;
+                               Z_TYPE_FLAGS_P(z) = 0;
                        } else {
                                if (!Z_REFCOUNTED_P(z)) {
                                        Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array));
@@ -299,7 +299,7 @@ static void zend_persist_zval(zval *z)
                                        zend_accel_store(Z_ARR_P(z), sizeof(zend_array));
                                        zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval);
                                        /* make immutable array */
-                                       Z_TYPE_FLAGS_P(z) = IS_TYPE_COPYABLE;
+                                       Z_TYPE_FLAGS_P(z) = 0;
                                        GC_SET_REFCOUNT(Z_COUNTED_P(z), 2);
                                        GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
                                        Z_ARRVAL_P(z)->u.flags |= HASH_FLAG_STATIC_KEYS;