#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 */
#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))
#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)
}
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));
}
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)
#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)
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); \
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);
}
}