}
print_flat_hash(Z_ARRVAL_P(expr));
ZEND_PUTS(")");
- if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
- }
+ GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
break;
case IS_OBJECT:
{
GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
}
print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
- if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
- }
+ GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
break;
case IS_OBJECT:
{
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
}
- if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) {
- GC_PROTECT_RECURSION(ht1);
- }
+ GC_TRY_PROTECT_RECURSION(ht1);
result = zend_hash_compare_impl(ht1, ht2, compar, ordered);
- if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(ht1);
- }
+ GC_TRY_UNPROTECT_RECURSION(ht1);
return result;
}
if (obj->handlers->get_debug_info) {
int is_temp;
ht = obj->handlers->get_debug_info(obj, &is_temp);
- if (ht && !is_temp && !(GC_FLAGS(ht) & GC_IMMUTABLE)) {
- GC_ADDREF(ht);
+ if (ht && !is_temp) {
+ GC_TRY_ADDREF(ht);
}
return ht;
}
case ZEND_PROP_PURPOSE_VAR_EXPORT:
case ZEND_PROP_PURPOSE_JSON:
ht = obj->handlers->get_properties(obj);
- if (ht && !(GC_FLAGS(ht) & GC_IMMUTABLE)) {
- GC_ADDREF(ht);
+ if (ht) {
+ GC_TRY_ADDREF(ht);
}
return ht;
default:
#define GC_DELREF(p) zend_gc_delref(&(p)->gc)
#define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc)
#define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc)
+#define GC_TRY_ADDREF(p) zend_gc_try_addref(&(p)->gc)
#define GC_TYPE_MASK 0x0000000f
#define GC_FLAGS_MASK 0x000003f0
return ++(p->refcount);
}
+static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) {
+ if (!(p->u.type_info & GC_IMMUTABLE)) {
+ ZEND_RC_MOD_CHECK(p);
+ ++p->refcount;
+ }
+}
+
static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) {
ZEND_ASSERT(p->refcount > 0);
ZEND_RC_MOD_CHECK(p);
#define PHP_JSON_HASH_PROTECT_RECURSION(_tmp_ht) \
do { \
- if (_tmp_ht && !(GC_FLAGS(_tmp_ht) & GC_IMMUTABLE)) { \
- GC_PROTECT_RECURSION(_tmp_ht); \
+ if (_tmp_ht) { \
+ GC_TRY_PROTECT_RECURSION(_tmp_ht); \
} \
} while (0)
#define PHP_JSON_HASH_UNPROTECT_RECURSION(_tmp_ht) \
do { \
- if (_tmp_ht && !(GC_FLAGS(_tmp_ht) & GC_IMMUTABLE)) { \
- GC_UNPROTECT_RECURSION(_tmp_ht); \
+ if (_tmp_ht) { \
+ GC_TRY_UNPROTECT_RECURSION(_tmp_ht); \
} \
} while (0)
}
} ZEND_HASH_FOREACH_END();
- if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(ht);
- }
-
+ GC_TRY_UNPROTECT_RECURSION(ht);
return cnt;
}
/* }}} */
src_zval = &tmp;
}
if (Z_TYPE_P(src_zval) == IS_ARRAY) {
- if (thash && !(GC_FLAGS(thash) & GC_IMMUTABLE)) {
- GC_PROTECT_RECURSION(thash);
+ if (thash) {
+ GC_TRY_PROTECT_RECURSION(thash);
}
ret = php_array_merge_recursive(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval));
- if (thash && !(GC_FLAGS(thash) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(thash);
+ if (thash) {
+ GC_TRY_UNPROTECT_RECURSION(thash);
}
if (!ret) {
return 0;
*(p++) = 'B';
*p = '\0';
}
- if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
- GC_PROTECT_RECURSION(ht);
- }
+ GC_TRY_PROTECT_RECURSION(ht);
php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type);
- if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
- GC_UNPROTECT_RECURSION(ht);
- }
+ GC_TRY_UNPROTECT_RECURSION(ht);
efree(newprefix);
} else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) {
/* Skip these types */