Skip to content

Commit

Permalink
Support PHP 7.3
Browse files Browse the repository at this point in the history
See [1] for the list of changes of the PHP internal API. The following
items are relevant here:

c. Array/Object recursion protection
e. AST and IS_CONSTANT
f. GC_REFCOUNT()

[1]: https://github.com/php/php-src/blob/PHP-7.3.16/UPGRADING.INTERNALS

Fixes #139.

@Totktonada: style and naming fixes.
  • Loading branch information
Sergey Son authored and Totktonada committed Mar 28, 2020
1 parent c900ba0 commit d1f2a0e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 27 deletions.
56 changes: 56 additions & 0 deletions src/php_tarantool.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,62 @@
# define smart_string_free_ex(...) smart_str_free_ex(__VA_ARGS__)
#endif

#if PHP_VERSION_ID < 70300
# define GC_SET_REFCOUNT(p, rc) do { \
GC_REFCOUNT((p)) = (rc); \
} while(0)
#endif /* PHP_VERSION_ID < 70300 */

#if PHP_VERSION_ID < 70300

# define ARRAY_PROTECT_RECURSION(data) do { \
if (Z_TYPE_P((data)) == IS_ARRAY && \
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P((data)))) \
{ \
Z_ARRVAL_P((data))->u.v.nApplyCount++; \
} \
} while(0)

# define ARRAY_UNPROTECT_RECURSION(data) do { \
if (Z_TYPE_P((data)) == IS_ARRAY && \
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P((data)))) \
{ \
Z_ARRVAL_P((data))->u.v.nApplyCount--; \
} \
} while(0)

# define ARRAY_IS_RECURSIVE(data) ( \
Z_TYPE_P(data) == IS_ARRAY && \
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P((data))) && \
Z_ARRVAL_P((data))->u.v.nApplyCount > 1 \
)

#else /* PHP_VERSION_ID < 70300 */

# define ARRAY_PROTECT_RECURSION(data) do { \
if (Z_TYPE_P((data)) == IS_ARRAY && \
!(GC_FLAGS(Z_ARRVAL_P((data))) & GC_IMMUTABLE)) \
{ \
GC_PROTECT_RECURSION(Z_ARRVAL_P((data))); \
} \
} while(0)

# define ARRAY_UNPROTECT_RECURSION(data) do { \
if (Z_TYPE_P((data)) == IS_ARRAY && \
!(GC_FLAGS(Z_ARRVAL_P((data))) & GC_IMMUTABLE)) \
{ \
GC_UNPROTECT_RECURSION(Z_ARRVAL_P((data))); \
} \
} while(0)

# define ARRAY_IS_RECURSIVE(data) ( \
Z_TYPE_P((data)) == IS_ARRAY && \
!(GC_FLAGS(Z_ARRVAL_P((data))) & GC_IMMUTABLE) && \
GC_IS_RECURSIVE(Z_ARRVAL_P((data))) \
)

#endif /* !(PHP_VERSION_ID < 70300)) */

extern zend_module_entry tarantool_module_entry;
#define phpext_tarantool_ptr &tarantool_module_entry

Expand Down
2 changes: 1 addition & 1 deletion src/tarantool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ PHP_METHOD(Tarantool, __construct) {
memset(&le, 0, sizeof(zend_resource));
le.type = php_tarantool_list_entry();
le.ptr = obj;
GC_REFCOUNT(&le) = 1;
GC_SET_REFCOUNT(&le, 1);

assert(plist_id != NULL);
if (zend_hash_update_mem(&EG(persistent_list), plist_id,
Expand Down
38 changes: 12 additions & 26 deletions src/tarantool_msgpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,12 @@ void php_mp_pack_array_recursively(smart_string *str, zval *val) {
size_t key_index = 0;
for (; key_index < n; ++key_index) {
data = zend_hash_index_find(ht, key_index);
if (!data || data == val || (Z_TYPE_P(data) == IS_ARRAY &&
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) &&
Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
if (!data || data == val || ARRAY_IS_RECURSIVE(data)) {
php_mp_pack_nil(str);
} else {
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount++;
ARRAY_PROTECT_RECURSION(data);
php_mp_pack(str, data);
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount--;
ARRAY_UNPROTECT_RECURSION(data);
}
}
}
Expand Down Expand Up @@ -165,16 +161,12 @@ void php_mp_pack_hash_recursively(smart_string *str, zval *val) {
break;
}
data = zend_hash_get_current_data_ex(ht, &pos);
if (!data || data == val || (Z_TYPE_P(data) == IS_ARRAY &&
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) &&
Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
if (!data || data == val || ARRAY_IS_RECURSIVE(data)) {
php_mp_pack_nil(str);
} else {
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount++;
ARRAY_PROTECT_RECURSION(data);
php_mp_pack(str, data);
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount--;
ARRAY_UNPROTECT_RECURSION(data);
}
}
}
Expand Down Expand Up @@ -407,15 +399,12 @@ size_t php_mp_sizeof_array_recursively(zval *val) {

for (; key_index < n; ++key_index) {
data = zend_hash_index_find(ht, key_index);
if (!data || data == val ||
(Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) && Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
if (!data || data == val || ARRAY_IS_RECURSIVE(data)) {
needed += php_mp_sizeof_nil();
} else {
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount++;
ARRAY_PROTECT_RECURSION(data);
needed += php_mp_sizeof(data);
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount--;
ARRAY_UNPROTECT_RECURSION(data);
}
}
return needed;
Expand Down Expand Up @@ -451,15 +440,12 @@ size_t php_mp_sizeof_hash_recursively(zval *val) {
break;
}
data = zend_hash_get_current_data_ex(ht, &pos);
if (!data || data == val ||
(Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) && Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
if (!data || data == val || ARRAY_IS_RECURSIVE(data)) {
needed += php_mp_sizeof_nil();
} else {
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount++;
ARRAY_PROTECT_RECURSION(data);
needed += php_mp_sizeof(data);
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
Z_ARRVAL_P(data)->u.v.nApplyCount--;
ARRAY_UNPROTECT_RECURSION(data);
}
}
return needed;
Expand Down
2 changes: 2 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ const char *tutils_op_to_string(zval *obj) {
return "RESOURCE";
case(IS_REFERENCE):
return "REFERENCE";
#if PHP_VERSION_ID < 70300
case(IS_CONSTANT):
return "CONSTANT";
#endif
case(IS_CONSTANT_AST):
return "CONSTANT_AST";
case(IS_CALLABLE):
Expand Down

0 comments on commit d1f2a0e

Please sign in to comment.